home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2002 #12
/
Amiga Plus CD - 2002 - No. 12.iso
/
Games
/
saga
/
source
/
saga.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-11-04
|
287KB
|
7,023 lines
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <utility/tagitem.h>
#include <graphics/gfx.h>
#include <clib/intuition_protos.h> // Object
#include <libraries/gadtools.h> // struct NewMenu
#include <devices/timer.h> // struct timeval
#include <clib/timer_protos.h>
#include <dos/dosextens.h> // struct Process
#include <libraries/asl.h> // ASL_FileRequest
#include <dos/dostags.h> // SYS_Output
#include <dos/datetime.h> // struct DateTime
#include <clib/dos_protos.h>
#include <libraries/locale.h>
#define OLD_GRAPHICS_GFXMACROS_H
#include <graphics/gfxmacros.h>
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE */
#include <assert.h>
#include "saga.h"
#define CATCOMP_NUMBERS
#define CATCOMP_CODE
#define CATCOMP_BLOCK
#include "saga_strings.h"
// #define ASSERT
#define NORMAL 0
#define GOOD 1
#define BAD 2
#define TURNS 20
#define UPPER 0
#define LOWER 1
#define SCOREDISTANCE 13
#define MESSAGEY 473
#define AMSIR 0
#define EON 1
#define GEOFU 2
#define ING 3
#define OGAL 4
#define SYGIL 5
#define HAGALL 1
#define IS 2
#define JARA 3
#define NIED 4
#define WYNN 5
#define YR 6
#define KEYBOARD 0
#define COUNTRY 1
#define COUNTER 2
#define ANYKEY 3
// scancodes
#define SCAN_F1 80
#define SCAN_F2 81
#define SCAN_F3 82
#define SCAN_F4 83
#define SCAN_F5 84
#define SCAN_F6 85
#define HELP 95
#define FIRSTQUALIFIER 96
#define LASTQUALIFIER 103
#define KEYUP 128 /* key release */
#define BLACK 0
#define WHITE 1
#define LIGHTGREY 2
#define MEDIUMGREY 3
#define DARKGREY 4
#define GREEN 5
#define BLUE 6
#define ORANGE 86
#define PURPLE 87
#define RED 88
#define FREY 0
#define LOKI 1
#define NJORD 2
#define ODIN 3
#define THOR 4
#define TYR 5
#define ABOUTXPIXEL 312
#define ABOUTYPIXEL 76
#define MN_PROJECT 0
#define MN_HELP 1
#define IN_NEW 0
#define IN_OPEN 1
#define IN_SAVE 3
#define IN_SAVEAS 4
#define IN_QUIT 6
#define IN_GAME_SUMMARY 0
#define IN_ABOUT 2
#define TITLEBAR "Saga 1.22"
#define VERSION "Saga 1.22 (5.11.2002)"
MODULE void place_monsters(void);
MODULE void place_jarls(void);
MODULE FLAG recruit(SLONG recruited, SLONG recruiterhero);
MODULE void flee(SLONG routertype, SLONG router, SLONG routerhero, SLONG routedtype, SLONG routed, SLONG routedhero);
MODULE void wound(SLONG woundertype, SLONG wounder, SLONG wounderhero, SLONG woundedtype, SLONG wounded, SLONG woundedhero);
MODULE void kill(SLONG killertype, SLONG killer, SLONG killerhero, SLONG killedtype, SLONG killed, SLONG killedhero);
MODULE void dobattle(SLONG defendtype, SLONG defender, SLONG attackhero);
MODULE SLONG d6(void);
MODULE SLONG getevent(SLONG mode, SLONG* countertype);
MODULE void say(SLONG position);
MODULE void newhero(SLONG whichhero, FLAG givesord);
MODULE void showcountry(SLONG country);
MODULE void phase1(void);
MODULE void phase2(void);
MODULE void phase3(void);
MODULE void newgame(void);
MODULE void gameloop(void);
MODULE void clearkybd(void);
MODULE void titlescreen(void);
MODULE void gain(SLONG whichhero, SLONG glory, SLONG luck);
MODULE void move(SLONG whichhero);
MODULE void attack(SLONG whichhero);
MODULE void helpabout(void);
MODULE void resettime(void);
MODULE void anykey(void);
MODULE SLONG getluck(SLONG whichhero);
MODULE FLAG loadgame(FLAG aslwindow);
MODULE void savegame(FLAG saveas);
MODULE SLONG odin_tyr(LONG whichhero, FLAG attacking);
MODULE void gods(SLONG whichhero);
MODULE void pray(SLONG whichhero);
MODULE void amiga_rout(SLONG routed, SLONG routedtype);
MODULE void human_rout(SLONG routedtype, SLONG routed, SLONG routerhero);
MODULE SLONG getmoves(SLONG countertype, SLONG whichcounter, FLAG freyfaxi);
MODULE void faxi_disappear(void);
MODULE void thor(SLONG whichhero);
MODULE void cast(SLONG caster, SLONG whichspell);
MODULE void darken(void);
MODULE SLONG checkcountry(WORD mousex, WORD mousey);
MODULE void infowindow(SLONG countertype, SLONG whichcounter);
MODULE void getdefender(SLONG attackhero, SLONG here);
MODULE FLAG needsord(SLONG countertype, SLONG counter);
MODULE void brosung(SLONG countertype, SLONG whichcounter);
MODULE void flash(SLONG country);
MODULE FLAG assess(SLONG countertype, SLONG counter);
MODULE void promote(SLONG whichhero, SLONG whichjarl);
MODULE void withdraw(SLONG whichhero);
MODULE FLAG asksord(SLONG countertype, SLONG counter, SLONG whichsord);
MODULE void asktreasure(SLONG countertype, SLONG counter, SLONG whichtreasure);
MODULE void pad(STRPTR thestring);
MODULE void print_location(SLONG whichcountry, SLONG index);
MODULE void print_sea(SLONG sea_value, SLONG index);
MODULE void print_hagall(SLONG hagall_value, SLONG index);
MODULE void print_paralyzed(SLONG paralyzed_value, SLONG index);
MODULE void print_routed(SLONG routed_value, SLONG index);
MODULE void amiga_attack(SLONG attackhero, SLONG defendtype, SLONG defender);
MODULE FLAG ask_faxi(SLONG countertype, SLONG whichcounter);
MODULE void saywho(SLONG countertype, SLONG counter, FLAG comma, FLAG lowercase);
MODULE void callforaid(SLONG passedtype, SLONG passed);
MODULE FLAG attackersleft(void);
MODULE void dospell(SLONG spell, SLONG caster);
MODULE void waitkey(void);
MODULE void summarywindow(void);
MODULE SLONG getattackers(SLONG whichhero, SLONG whichcountry);
MODULE struct
{ UBYTE red, green, blue;
} taxcolours[10 + 1] =
{ { 0, 5, 0 }, // tax 0 (unused)
{ 1, 6, 1 }, // tax 1 (unused)
{ 2, 7, 2 }, // tax 2
{ 3, 8, 3 }, // tax 3
{ 4, 9, 4 }, // tax 4
{ 5, 10, 5 }, // tax 5
{ 6, 11, 6 }, // tax 6
{ 7, 12, 7 }, // tax 7
{ 8, 13, 8 }, // tax 8
{ 9, 14, 9 }, // tax 9
{ 10, 15, 10 } // tax 10
};
#define ABOUTLINES 3
struct
{ WORD x, y;
TEXT text[80 + 1];
} about[ABOUTLINES + 1] =
{ {72, 27},
{72, 35},
{72, 51},
{72, 59}
};
#define MENUENTRIES 12
struct NewMenu NewMenu[MENUENTRIES + 1] =
{ { NM_TITLE, "", 0 , 0, 0, 0}, // 0
{ NM_ITEM, "", "" , 0, 0, 0}, // 1
{ NM_ITEM, "", "" , 0, 0, 0}, // 2
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, 0}, // 3
{ NM_ITEM, "", "" , 0, 0, 0}, // 4
{ NM_ITEM, "", "" , 0, 0, 0}, // 5
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, 0}, // 6
{ NM_ITEM, "", "" , 0, 0, 0}, // 7
{ NM_TITLE, "", 0 , 0, 0, 0}, // 8
{ NM_ITEM, "", "" , 0, 0, 0}, // 9
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, 0}, // 10
{ NM_ITEM, "", "?", 0, 0, 0}, // 11
{ NM_END, NULL, 0 , 0, 0, 0} // 12
};
// These are better to not be allocated on the stack
MODULE ULONG table1[] = {(8L << 16) + 0,
0x00000000, 0x00000000, 0x00000000, // 0 (BLACK)
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 1 (WHITE)
0xCCCCCCCC, 0xCCCCCCCC, 0xCCCCCCCC, // 2 (LIGHTGREY)
0x99999999, 0x99999999, 0x99999999, // 3 (MEDIUMGREY)
0x66666666, 0x66666666, 0x66666666, // 4 (DARKGREY)
0x66666666, 0xFFFFFFFF, 0x66666666, // 5 (GREEN)
0x88888888, 0x88888888, 0xFFFFFFFF, // 6 (BLUE)
0x00000000, 0x00000000, 0x00000000, // 7
0};
MODULE ULONG table2[] = {(54L << 16) + 74,
0x99999999, 0x99999999, 0xFFFFFFFF, // 74
0x99999999, 0xFFFFFFFF, 0x99999999, // 75
0xFFFFFFFF, 0xCCCCCCCC, 0x99999999, // 76
0xFFFFFFFF, 0x99999999, 0xFFFFFFFF, // 77
0xFFFFFFFF, 0xFFFFFFFF, 0x99999999, // 78
0x00000000, 0x00000000, 0x00000000, // 79
0x00000000, 0x00000000, 0x00000000, // 80
0x00000000, 0x00000000, 0x99999999, // 81
0x00000000, 0x00000000, 0x00000000, // 82
0x00000000, 0x00000000, 0x99999999, // 83
0x00000000, 0x00000000, 0x00000000, // 84
0x00000000, 0x00000000, 0x99999999, // 85
0xFFFFFFFF, 0x99999999, 0x88888888, // 86 (ORANGE)
0xFFFFFFFF, 0x88888888, 0xFFFFFFFF, // 87 (PURPLE)
0xFFFFFFFF, 0x55555555, 0x55555555, // 88 (RED)
0x00000000, 0x00000000, 0x00000000, // 89
0x00000000, 0x00000000, 0x00000000, // 90
0x00000000, 0x00000000, 0x00000000, // 91
0x00000000, 0x00000000, 0x00000000, // 92
0x00000000, 0x00000000, 0xFFFFFFFF, // 93
0x10101010, 0x14141414, 0xFFFFFFFF, // 94
0x1F1F1F1F, 0x23232323, 0xFFFFFFFF, // 95
0x2E2E2E2E, 0x32323232, 0xFFFFFFFF, // 96
0x3D3D3D3D, 0x41414141, 0xFFFFFFFF, // 97
0x4C4C4C4C, 0x4F4F4F4F, 0xFFFFFFFF, // 98
0x5B5B5B5B, 0x5E5E5E5E, 0xFFFFFFFF, // 99
0x6A6A6A6A, 0x6D6D6D6D, 0xFFFFFFFF, // 100
0x79797979, 0x7C7C7C7C, 0xFFFFFFFF, // 101
0x87878787, 0x89898989, 0xFFFFFFFF, // 102
0x96969696, 0x98989898, 0xFFFFFFFF, // 103
0xA5A5A5A5, 0xA7A7A7A7, 0xFFFFFFFF, // 104
0xB4B4B4B4, 0xB6B6B6B6, 0xFFFFFFFF, // 105
0xC3C3C3C3, 0xC4C4C4C4, 0xFFFFFFFF, // 106
0xD2D2D2D2, 0xD3D3D3D3, 0xFFFFFFFF, // 107
0xE1E1E1E1, 0xE2E2E2E2, 0xFFFFFFFF, // 108
0xF0F0F0F0, 0xF1F1F1F1, 0xFFFFFFFF, // 109
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 110
0x00000000, 0x00000000, 0xFFFFFFFF, // 111
0x00000000, 0x88888888, 0xFFFFFFFF, // 112
0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, // 113
0x00000000, 0xFFFFFFFF, 0x88888888, // 114
0x00000000, 0xFFFFFFFF, 0x00000000, // 115
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, // 116
0xFFFFFFFF, 0xDDDDDDDD, 0x00000000, // 117
0xFFFFFFFF, 0xC5C5C5C5, 0x00000000, // 118
0xFFFFFFFF, 0xA7A7A7A7, 0x00000000, // 119
0xFFFFFFFF, 0x89898989, 0x00000000, // 120
0xFFFFFFFF, 0x72727272, 0x00000000, // 121
0xFFFFFFFF, 0x54545454, 0x00000000, // 122
0xFFFFFFFF, 0x36363636, 0x00000000, // 123
0xFFFFFFFF, 0x1E1E1E1E, 0x00000000, // 124
0xFFFFFFFF, 0x00000000, 0x00000000, // 125
0x00000000, 0x00000000, 0x00000000, // 126
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 127
0};
MODULE struct NewGadget SpeedGadget =
{ 300, 312,
128, 13,
"",
NULL,
NULL,
NULL,
NULL,
NULL
}, CycleGadget[HEROES + 1] = {
{ 300, 200,
128, 13,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
},
{ 300, 216,
128, 13,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
},
{ 300, 232,
128, 13,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
},
{ 300, 248,
128, 13,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
},
{ 300, 264,
128, 13,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
},
{ 300, 280,
128, 13,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
}
};
#define HERO_STRENGTH 5
#define HERO_MOVES 4
#define RUNES 5
SLONG cycleheropos[HEROES + 1] =
{ 2,
3,
5,
3,
0,
3
};
MODULE struct
{ UBYTE red, green, blue;
} herocolour[HEROES + 1] =
{ { 15, 12, 6}, // orange
{ 15, 6, 6}, // red
{ 15, 15, 3}, // yellow
{ 6, 15, 15}, // cyan
{ 10, 10, 15}, // light blue
{ 15, 6, 15} // purple
};
STRPTR trueheroname[HEROES + 1] =
{ "Beowulf",
"Brunhild",
"Egil",
"Ragnar",
"Siegfried",
"Starkad"
}, cycleheroname[HEROES + 1] =
{ " Beowulf:",
" Brunhild:",
" Egil:",
" Ragnar:",
"Siegfried:",
" Starkad:"
}, runename[RUNES + 1] =
{ "Amsir",
"Eon",
"Geofu",
"Ing",
"Ogal",
"Sygil",
};
AGLOBAL struct JarlStruct jarl[JARLS + 1] =
{ { 2, 3, "Amleth" },
{ 3, 3, "Bjarki" },
{ 3, 3, "Erik" },
{ 2, 2, "Eyjolf" },
{ 2, 2, "Gretter" },
{ 2, 2, "Hagen" },
{ 2, 3, "Harald" },
{ 2, 3, "Helgi" },
{ 2, 2, "Hengist" },
{ 2, 2, "Horsi" },
{ 4, 2, "Hrolfwulf" },
{ 4, 2, "Ivar" },
{ 4, 3, "Kari" },
{ 2, 3, "Skallagrim"},
{ 3, 3, "Thorolf" },
{ 2, 3, "Thorvald" },
{ 3, 3, "Welland" },
{ 3, 3, "Wiglar" }
};
#define BEOWULF 0
#define BRUNHILD 1
#define EGIL 2
#define RAGNAR 3
#define SIEGFRIED 4
#define STARKAD 5
AGLOBAL struct HeroStruct hero[HEROES + 1];
#define BALMUNG 0
#define DRAGVENDILL 1
#define GRAM 2
#define HRUNTING 3
#define LOVI 4
#define TYRFING 5
struct SordStruct sord[SORDS + 1] =
{ { "Balmung (+1)" },
{ "Dragvendill (+2)"},
{ "Gram (+2)" },
{ "Hrunting (+1)" },
{ "Lovi (+1)" },
{ "Tyrfing (+2)" }
};
#define BROSUNGNECKLACE 0
#define FREYFAXI 1
#define MAGICSHIRT 2
#define MAILCOAT 3
struct TreasureStruct treasure[TREASURES + 1] =
{ {"" },
{"Frey Faxi"},
{"" },
{"" }
};
#define DRAGON 0
#define DROW 1
#define GIANT 2
#define GHOST 3
#define TROLL 4
#define WITCH 5
AGLOBAL struct MonsterStruct monster[MONSTERS + 1] =
{ { DRAGON, 10, 1, "Aludreng" },
{ DRAGON, 11, 2, "Fafnir" },
{ DRAGON, 10, 2, "Glerion" },
{ DRAGON, 10, 2, "Hallbjorn"},
{ DRAGON, 9, 3, "Istvan" },
{ DRAGON, 11, 2, "Stigandi" },
{ DROW, 2, 2, "Atli" },
{ DROW, 3, 1, "Gizur" },
{ DROW, 3, 1, "Hallgerd" },
{ GHOST, 4, 2, "Gizar" },
{ GHOST, 4, 1, "Glam" },
{ GHOST, 4, 0, "Gunnar" },
{ GHOST, 4, 0, "Hrap" },
{ GHOST, 4, 1, "Mord" },
{ GHOST, 4, 1, "Trogrier" },
{ GIANT, 7, 0, "Angantyr" },
{ GIANT, 6, 1, "Hall" },
{ GIANT, 8, 1, "Storvick" },
{ TROLL, 6, 2, "Grendall" },
{ TROLL, 5, 2, "Hallbjorn"},
{ TROLL, 5, 1, "Hauk" },
{ TROLL, 6, 1, "Hogshead" },
{ TROLL, 5, 3, "Onund" },
{ TROLL, 5, 2, "Svinafell"},
{ WITCH, 3, 4, "Gerdrak" },
{ WITCH, 3, 5, "Grunhild" },
{ WITCH, 4, 4, "Hedin" }
};
/* These are the statistical distribution of the taxation factors:
4x 2 tax
10x 3 tax
3x 4 tax
3x 5 tax
6x 6 tax
4x 7 tax
1x 8 tax
2x 9 tax
3x 10 tax */
#define LAND 0
#define SEA 1
#define ISLE 2
#define PENINSULA 3
AGLOBAL struct WorldStruct world[36 + 30] =
{ {590, 39, 3, LAND, "Finmark" , 1, -1, -1, -1, -1, -1, -1, -1}, // 1:1 ( 0) (inland)
{584, 104, 3, LAND, "Trondheim", 0, 2, 3, 60, -1, -1, -1, -1}, // 1:2 ( 1)
{489, 102, 6, LAND, "Mordaland", 1, 3, 4, 55, 59, 60, -1, -1}, // 1:3 ( 2)
{573, 173, 2, LAND, "Upland", 1, 2, 4, 5, 6, -1, -1, -1}, // 1:4 ( 3) (inland)
{451, 176, 5, LAND, "Agdar", 2, 3, 5, 48, 49, 54, 55, -1}, // 1:5 ( 4)
{514, 201, 3, LAND, "Romeirt", 3, 4, 6, 7, 47, 48, -1, -1}, // 1:6 ( 5)
{569, 233, 7, LAND, "Jamtland", 3, 5, 7, 8, 65, -1, -1, -1}, // 2:1 ( 6)
{512, 262, 6, LAND, "Vester Gotland", 5, 6, 8, 9, 47, -1, -1, -1}, // 2:2 ( 7)
{549, 305, 7, LAND, "Oster Gotland", 6, 7, 9, 63, 65, -1, -1, -1}, // 2:3 ( 8)
{502, 323, 4, LAND, "Suder Gotland", 7, 8, 11, 47, 63, -1, -1, -1}, // 2:4 ( 9)
{420, 287, 6, LAND, "Juteland", 11, 14, 46, 47, 48, 49, -1, -1}, // 2:5 (10)
{441, 344, 3, ISLE, "Scandia", 9, 10, 12, 13, 14, 47, 63, -1}, // 2:6 (11)
{522, 442, 4, LAND, "Pomerania", 11, 13, 63, 64, -1, -1, -1, -1}, // 3:1 (12)
{393, 421, 6, LAND, "Saxony", 11, 12, 14, 15, 16, 46, -1, -1}, // 3:2 (13)
{392, 372, 7, LAND, "Anglia", 10, 11, 13, 46, -1, -1, -1, -1}, // 3:3 (14)
{305, 383, 7, LAND, "Fenland", 13, 16, 17, 44, 45, 46, -1, -1}, // 3:4 (15)
{305, 434, 10, LAND, "Rhineland", 13, 15, 17, -1, -1, -1, -1, -1}, // 3:5 (16) (inland)
{242, 428, 9, LAND, "Frisia", 15, 16, 18, 44, -1, -1, -1, -1}, // 3:6 (17)
{175, 438, 3, LAND, "Frankland", 17, 19, 43, 44, -1, -1, -1, -1}, // 4:1 (18)
{ 97, 439, 10, LAND, "Armorica", 18, 42, 43, -1, -1, -1, -1, -1}, // 4:2 (19)
{ 75, 318, 2, LAND, "Cornwall", 21, 42, 43, -1, -1, -1, -1, -1}, // 4:3 (20)
{109, 333, 10, LAND, "Wessex", 20, 22, 23, 24, 25, 42, 43, -1}, // 4:4 (21)
{153, 354, 9, LAND, "Sussex", 21, 23, 24, 43, 44, -1, -1, -1}, // 4:5 (22)
{190, 329, 6, LAND, "East Anglia", 22, 24, 44, 45, -1, -1, -1, -1}, // 4:6 (23)
{148, 313, 3, LAND, "Mercia", 21, 22, 23, 25, 26, 27, 45, 51}, // 5:1 (24)
{108, 287, 3, LAND, "Daffyd", 21, 24, 26, 41, 42, -1, -1, -1}, // 5:2 (25)
{145, 268, 2, LAND, "Gwynedd", 24, 25, 27, 41, -1, -1, -1, -1}, // 5:3 (26)
{186, 217, 8, LAND, "Northumberland", 24, 26, 28, 41, 51, 52, -1, -1}, // 5:4 (27)
{178, 157, 3, LAND, "Dalriada", 27, 29, 30, 40, 41, 52, -1, -1}, // 5:5 (28)
{222, 130, 5, LAND, "Caledonia", 28, 30, 52, 57, -1, -1, -1, -1}, // 5:6 (29)
{230, 85, 2, PENINSULA, "Pictland", 28, 29, 31, 40, 57, 58, 61, 62}, // 6:1 (30)
{167, 66, 3, ISLE, "Hebrides", 30, 36, 39, 40, 62, -1, -1, -1}, // 6:2 (31)
{ 62, 40, 3, LAND, "Thule", 36, 37, -1, -1, -1, -1, -1, -1}, // 6:3 (32)
{ 54, 162, 5, LAND, "Connacht", 34, 35, 38, 39, -1, -1, -1, -1}, // 6:4 (33)
{109, 162, 4, LAND, "Ulster", 33, 35, 39, 40, 41, -1, -1, -1}, // 6:5 (34)
{ 60, 203, 6, LAND, "Leinster", 33, 34, 41, -1, -1, -1, -1, -1}, // 6:6 (35)
{134, 32, 0, SEA, "", 31, 32, 37, 39, -1, -1, -1, -1}, // (36)
{ 52, 94, 0, SEA, "", 32, 36, 38, 39, -1, -1, -1, -1}, // (37)
{ 53, 130, 0, SEA, "", 33, 37, 39, -1, -1, -1, -1, -1}, // (38)
{ 82, 118, 0, SEA, "", 31, 33, 34, 36, 37, 38, 40, -1}, // (39)
{137, 165, 0, SEA, "", 28, 30, 31, 34, 39, 41, -1, -1}, // (40)
{116, 225, 0, SEA, "", 25, 26, 27, 28, 34, 35, 40, 42}, // (41)
{ 57, 292, 0, SEA, "", 19, 20, 21, 25, 41, 43, -1, -1}, // (42)
{127, 389, 0, SEA, "", 18, 19, 20, 21, 22, 42, 44, -1}, // (43)
{217, 370, 0, SEA, "", 15, 17, 18, 22, 23, 43, 45, -1}, // (44)
{261, 328, 0, SEA, "", 15, 23, 24, 44, 46, 50, 51, -1}, // (45)
{343, 334, 0, SEA, "", 10, 13, 14, 15, 45, 49, 50, -1}, // (46)
{467, 282, 0, SEA, "Kategatt", 5, 7, 9, 10, 11, 48, -1, -1}, // (47)
{445, 229, 0, SEA, "Skagerrak", 4, 5, 10, 47, 49, -1, -1, -1}, // (48)
{376, 270, 0, SEA, "", 4, 10, 48, 46, 50, 54, -1, -1}, // (49)
{311, 268, 0, SEA, "", 45, 46, 49, 51, 53, 54, -1, -1}, // (50) (deep waters)
{240, 258, 0, SEA, "", 24, 27, 45, 50, 52, 53, -1, -1}, // (51)
{248, 193, 0, SEA, "", 27, 28, 29, 51, 53, 56, 57, -1}, // (52)
{324, 196, 0, SEA, "", 50, 51, 52, 54, 55, 56, -1, -1}, // (53) (deep waters)
{379, 186, 0, SEA, "", 4, 49, 50, 53, 55, -1, -1, -1}, // (54)
{386, 124, 0, SEA, "", 2, 4, 53, 54, 56, 58, 59, -1}, // (55)
{318, 134, 0, SEA, "", 52, 53, 55, 57, 58, -1, -1, -1}, // (56) (deep waters)
{267, 133, 0, SEA, "", 29, 30, 52, 56, 58, -1, -1, -1}, // (57)
{338, 90, 0, SEA, "", 30, 55, 56, 57, 59, 60, 61, -1}, // (58)
{427, 73, 0, SEA, "", 2, 55, 58, 60, -1, -1, -1, -1}, // (59)
{456, 27, 0, SEA, "", 1, 2, 58, 59, 61, -1, -1, -1}, // (60)
{341, 47, 0, SEA, "", 30, 58, 60, 62, -1, -1, -1, -1}, // (61)
{257, 44, 0, SEA, "", 30, 31, 61, -1, -1, -1, -1, -1}, // (62)
{509, 385, 0, SEA, "", 8, 9, 11, 12, 64, 65, -1, -1}, // (63)
{587, 404, 0, SEA, "", 12, 63, 65, -1, -1, -1, -1, -1}, // (64)
{587, 345, 0, SEA, "", 6, 8, 63, 64, -1, -1, -1, -1} // (65)
};
#define NONE 0
#define HUMAN 1
#define AMIGA 2
#define MAXLINES 45
#define LEFTSIDE 0
#define RIGHTSIDE 1
IMPORT struct ExecBase* SysBase;
IMPORT struct Custom custom;
AGLOBAL struct GfxBase* GfxBase = NULL;
AGLOBAL struct GadToolsBase* GadToolsBase = NULL;
AGLOBAL struct IntuitionBase* IntuitionBase = NULL;
AGLOBAL struct LocaleBase* LocaleBase = NULL;
AGLOBAL struct Library* TimerBase = NULL;
AGLOBAL struct ASLBase* ASLBase = NULL;
AGLOBAL struct Window *MainWindowPtr = NULL,
*HelpWindowPtr = NULL,
*InfoWindowPtr = NULL;
AGLOBAL UWORD DisplayDepth = DEPTH;
AGLOBAL struct Screen* ScreenPtr = NULL;
MODULE WORD speed = 4;
MODULE UBYTE IOBuffer[600];
MODULE ULONG DisplayID = HIRES_KEY | PAL_MONITOR_ID | LACE,
DisplayWidth = SCREENXPIXEL,
DisplayHeight = SCREENYPIXEL;
MODULE struct RDArgs* ArgsPtr = NULL;
MODULE struct FileRequester* ASLRqPtr = NULL;
MODULE struct Process* ProcessPtr = NULL;
MODULE struct Menu* MenuPtr = NULL;
MODULE struct VisualInfo* VisualInfoPtr = NULL;
MODULE APTR OldWindowPtr = NULL;
MODULE FLAG gameover,
loaded,
cliload = FALSE;
MODULE SLONG faxirides,
tickwait = 7, // measured in intuiticks (10ths of a second)
turn,
order[HEROES + 1];
MODULE TEXT abouttitle[80 + 1],
saystring[256 + 1],
numberstring[13 + 1],
titlestring[80 + 1],
pathname[256 + 1],
line[2][MAXLINES + 1][80 + 1];
MODULE struct Gadget *SpeedGadgetPtr = NULL,
*CycleGadgetPtr[HEROES + 1] = {NULL, NULL, NULL, NULL, NULL, NULL},
*GListPtr = NULL,
*PrevGadgetPtr = NULL;
MODULE struct LocaleInfo li;
MODULE STRPTR CycleOptions[4],
monstertypes[6],
runedesc[RUNES + 1];
#define ONEKEY_YES 0
#define ONEKEY_NO 1
#define ONEKEY_WITHDRAW 2
#define ONEKEY_RESTART 3
#define ONEKEY_TRANSFER 4
#define ONEKEY_GLORY 5
#define ONEKEY_LUCK 6
#define ONEKEYS ONEKEY_LUCK
TEXT onekey[ONEKEYS + 1] =
{ 'Y', 'N', 'W', 'R', 'T', 'G', 'L'
};
MODULE void place_monsters(void)
{ /* .taken = FALSE: the monster is in the "pile of monsters" (spare).
TRUE : the monster is either on the board or dead. */
SLONG whichhero, whichmonster, whichtreasure;
FLAG available, ok;
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].alive)
{ available = FALSE;
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ if (!monster[whichmonster].taken)
{ available = TRUE;
break;
} }
if (available)
{ do
{ whichmonster = rand() % (MONSTERS + 1);
} while (monster[whichmonster].taken);
monster[whichmonster].taken =
monster[whichmonster].alive = TRUE;
monster[whichmonster].where = rand() % 36;
monster[whichmonster].sea = NORMAL;
monster[whichmonster].hagall = FALSE;
if (monster[whichmonster].species == DRAGON)
{ ok = FALSE;
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if (!treasure[whichtreasure].taken)
{ ok = TRUE; // at least one treasure is available
break; // for speed
} }
if (ok)
{ do
{ whichtreasure = rand() % (TREASURES + 1);
} while (treasure[whichtreasure].taken);
treasure[whichtreasure].taken = TRUE;
treasure[whichtreasure].possessortype = MONSTER;
treasure[whichtreasure].possessor = whichmonster;
treasure[whichtreasure].where = -1;
monster[whichmonster].wealth = 0;
} else
{ monster[whichmonster].wealth = 20;
} }
else
{ monster[whichmonster].wealth = 0;
}
// we don't unslot newborn counters
move_monster(whichmonster, FALSE);
} } } }
MODULE void place_jarls(void)
{ FLAG available;
SLONG whichhero, whichjarl;
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].alive)
{ available = FALSE;
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (!jarl[whichjarl].taken)
{ available = TRUE;
break;
} }
if (available)
{ do
{ whichjarl = rand() % (JARLS + 1);
} while (jarl[whichjarl].taken);
jarl[whichjarl].taken =
jarl[whichjarl].alive = TRUE;
jarl[whichjarl].wealth = 0;
jarl[whichjarl].where =
jarl[whichjarl].homewhere = rand() % 36;
jarl[whichjarl].hero = -1;
jarl[whichjarl].sea = NORMAL;
jarl[whichjarl].hagall =
jarl[whichjarl].loseturn = FALSE;
hidejarl(whichjarl, FALSE);
// we don't unslot newborn counters
move_jarl(whichjarl, FALSE);
} } } }
int main(int argc, char** argv)
{ struct TextAttr Topaz8 =
{ (STRPTR) "topaz.font", 8, FS_NORMAL, FPF_ROMFONT | FPF_DESIGNED
};
struct DateTime DateTime;
struct ScreenModeRequester* smr;
BPTR FileHandle /* = NULL */ ;
FLAG ok;
TEXT datestring[LEN_DATSTRING],
weekdaystring[LEN_DATSTRING],
tempstring[1 + 1],
smrstring[80 + 1],
supergels[2];
SLONG whichcountry, whichhero,
args[7] = {0L, 0L, 0L, 0L, 0L, 0L, 0L};
UWORD Pens[13] =
{ BLACK, /* DETAILPEN text in title bar */
WHITE, /* BLOCKPEN fill title bar */
WHITE, /* TEXTPEN regular text on BACKGROUNDPEN (was BLACK) */
LIGHTGREY, /* SHINEPEN bright edge */
DARKGREY, /* SHADOWPEN dark edge */
BLUE, /* FILLPEN filling active window borders
and selected gadgets */
BLACK, /* FILLTEXTPEN text rendered over FILLPEN */
BLACK, /* BACKGROUNDPEN background colour (was BLUE) */
ORANGE, /* HIGHLIGHTTEXTPEN highlighted text on BACKGROUNDPEN
and used against BLOCKPEN in ASL
save requesters */
BLACK, /* BARDETAILPEN text/detail in screen-bar/menus */
WHITE, /* BARBLOCKPEN screen-bar/menus fill */
BLACK, /* BARTRIMPEN trim under screen-bar */
(UWORD) ~0 /* and used against BLOCKPEN in ASL save requesters */
};
/* Colour allocations are as follows:
colours 0-6 are used by the game itself.
colour 7 is the black of the map.
colours 8-43 are map land colours, except that
colours 17-19 are mouse pointer colours.
colours 44-73 are map sea colours.
colour 74 is hero counter colour (blue).
colour 75 is jarl counter colour (green).
colour 76 is monster counter colour (orange).
colour 77 is treasure counter colour (purple).
colour 78 is sword counter colour (yellow).
colour 79 is the black of the counters.
colour 80 is Scandian coastline.
colour 81 is Scandian sea.
colour 82 is Pictish coastline.
colour 83 is Pictish sea.
colour 84 is Hebridean coastline.
colour 85 is Hebridean sea.
colours 86-88 are used by the game itself.
colour 89 is Suder Gotland land (replacement for colour 17).
colour 90 is Juteland land (replacement for colour 18).
colour 91 is Scandian land (replacement for colour 19).
colours 92-110 are used for the Saga logo.
colours 111-125 (and others) are used for the Amigan Software logo.
colour 126 is selected menu text.
colour 127 is selected menu background.
Start of program.
version embedding into executable */
if (0) /* that is, never */
{ Printf("%s\n", VERSION);
}
// before the first possible point of failure
init_counters();
for (whichcountry = 0; whichcountry <= 65; whichcountry++)
{ world[whichcountry].hero = -1;
}
pathname[0] = 0;
if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39L)))
{ strcpy(saystring, "Saga: Can't open intuition.library V39+!)\n");
Write(Output(), saystring, strlen(saystring));
cleanexit(EXIT_FAILURE);
}
ProcessPtr = (struct Process *) FindTask(NULL);
if (SysBase->LibNode.lib_Version < 36L)
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open exec.library V36+!\0", 24);
cleanexit(EXIT_FAILURE);
}
// From this point onwards, we can be sure we have Kickstart 2.0+...
if (GetVar("cybergfx/supergels", supergels, 2, NULL) == 1)
{ if (supergels[0] == '1')
{ Printf("Saga: ENV:cybergfx/supergels must be cleared to 0 before playing!\n");
cleanexit(EXIT_FAILURE);
} }
/* NOTES FOR TRANSLATORS:
MSG_CHAR_FOO messages are single-character strings which are the
first letter of the relevant word. MSG_UNCHAR_FOO messages are the
rest of the word. Eg. in English, MSG_CHAR_GLORY is "G" and
MSG_UNCHAR_GLORY is "lory". They must each be different among their
'set' (yes/no, glory/luck, restart/transfer/withdraw). */
li.li_Catalog = NULL;
if (LocaleBase = OpenLibrary("locale.library", 38))
{ li.li_LocaleBase = LocaleBase;
li.li_Catalog = OpenCatalog(NULL, "Saga.catalog", TAG_DONE);
}
strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
onekey[ONEKEY_YES] = tempstring[0];
strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
onekey[ONEKEY_NO] = tempstring[0];
strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_WITHDRAW, "W"));
onekey[ONEKEY_WITHDRAW] = tempstring[0];
strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_RESTART, "R"));
onekey[ONEKEY_RESTART] = tempstring[0];
strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_TRANSFER, "T"));
onekey[ONEKEY_TRANSFER] = tempstring[0];
strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_GLORY, "G"));
onekey[ONEKEY_GLORY] = tempstring[0];
strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_LUCK, "L"));
onekey[ONEKEY_LUCK] = tempstring[0];
CycleOptions[0] = GetCatalogStr(li.li_Catalog, MSG_GADGET_NONE, "None");
CycleOptions[1] = GetCatalogStr(li.li_Catalog, MSG_HUMAN, "Human");
CycleOptions[2] = "Amiga";
CycleOptions[3] = NULL;
strcpy(abouttitle, GetCatalogStr(li.li_Catalog, MSG_ABOUT, "About"));
strcat(abouttitle, " Saga");
strcpy(about[0].text, TITLEBAR);
about[1].text[0] = 0;
DateTime.dat_Format = FORMAT_DOS;
DateTime.dat_Flags = NULL;
DateTime.dat_StrDate = "5-Nov-02";
DateTime.dat_StrDay = NULL;
DateTime.dat_StrTime = NULL;
DateTime.dat_Stamp.ds_Minute = 0;
DateTime.dat_Stamp.ds_Tick = 0;
if (StrToDate(&DateTime))
{ // DateTime.dat_Stamp is now filled
DateTime.dat_Format = FORMAT_DEF;
DateTime.dat_Flags = NULL;
DateTime.dat_StrDate = datestring;
DateTime.dat_StrDay = weekdaystring;
DateTime.dat_StrTime = NULL;
if (DateToStr(&DateTime))
{ strcpy(about[1].text, weekdaystring);
strcat(about[1].text, " ");
strcat(about[1].text, datestring);
} }
strcpy(about[2].text, "© 2002 Amigan Software");
strcpy(about[3].text, GetCatalogStr(li.li_Catalog, MSG_BY, "By"));
strcat(about[3].text, " James R. Jacobs");
monstertypes[0] = GetCatalogStr(li.li_Catalog, MSG_DRAGON, "Dragon");
monstertypes[1] = GetCatalogStr(li.li_Catalog, MSG_DROW , "Drow" );
monstertypes[2] = GetCatalogStr(li.li_Catalog, MSG_GIANT , "Giant" );
monstertypes[3] = GetCatalogStr(li.li_Catalog, MSG_GHOST , "Ghost" );
monstertypes[4] = GetCatalogStr(li.li_Catalog, MSG_TROLL , "Troll" );
monstertypes[5] = GetCatalogStr(li.li_Catalog, MSG_WITCH , "Witch" );
runedesc[0] = GetCatalogStr(li.li_Catalog, MSG_THE_GODS, "rune of the gods");
runedesc[1] = GetCatalogStr(li.li_Catalog, MSG_TIME , "rune of time" );
runedesc[2] = GetCatalogStr(li.li_Catalog, MSG_PROPERTY, "rune of property");
runedesc[3] = GetCatalogStr(li.li_Catalog, MSG_HEALING , "rune of healing" );
runedesc[4] = GetCatalogStr(li.li_Catalog, MSG_FURY , "rune of fury" );
runedesc[5] = GetCatalogStr(li.li_Catalog, MSG_THE_SUN , "rune of the sun" );
for (whichcountry = 36; whichcountry <= 39; whichcountry++)
{ world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_ATLANTIC_OCEAN , "Atlantic Ocean" );
}
for (whichcountry = 40; whichcountry <= 42; whichcountry++)
{ world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_IRISH_SEA , "Irish Sea" );
}
for (whichcountry = 43; whichcountry <= 44; whichcountry++)
{ world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_ENGLISH_CHANNEL, "English Channel");
}
for (whichcountry = 45; whichcountry <= 62; whichcountry++)
{ if (whichcountry < 47 || whichcountry > 48)
{ world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_NORTH_SEA , "North Sea" );
} }
for (whichcountry = 63; whichcountry <= 65; whichcountry++)
{ world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_BALTIC_SEA , "Baltic Sea" );
}
treasure[BROSUNGNECKLACE].name = GetCatalogStr(li.li_Catalog, MSG_BROSUNG_NECKLACE, "Brosung Necklace");
treasure[MAGICSHIRT].name = GetCatalogStr(li.li_Catalog, MSG_MAGIC_SHIRT , "Magic Shirt" );
treasure[MAILCOAT].name = GetCatalogStr(li.li_Catalog, MSG_MAIL_COAT , "Mail Coat" );
NewMenu[0].nm_Label = GetCatalogStr(li.li_Catalog, MSG_PROJECT , "Project" );
NewMenu[1].nm_Label = GetCatalogStr(li.li_Catalog, MSG_NEW , "New" );
NewMenu[1].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_NEW , "N" );
NewMenu[2].nm_Label = GetCatalogStr(li.li_Catalog, MSG_OPEN , "Open..." );
NewMenu[2].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_OPEN , "O" );
NewMenu[4].nm_Label = GetCatalogStr(li.li_Catalog, MSG_SAVE , "Save" );
NewMenu[4].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_SAVE , "S" );
NewMenu[5].nm_Label = GetCatalogStr(li.li_Catalog, MSG_SAVE_AS , "Save As...");
NewMenu[5].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_SAVE_AS, "A" );
NewMenu[7].nm_Label = GetCatalogStr(li.li_Catalog, MSG_QUIT , "Quit" );
NewMenu[7].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_QUIT , "Q" );
NewMenu[8].nm_Label = GetCatalogStr(li.li_Catalog, MSG_HELP , "Help" );
NewMenu[9].nm_Label = GetCatalogStr(li.li_Catalog, MSG_GAME_SUMMARY2 , "Game Summary...");
NewMenu[9].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_GAME_SUMMARY, "G" );
NewMenu[11].nm_Label = GetCatalogStr(li.li_Catalog, MSG_ABOUT2 , "About..." );
SpeedGadget.ng_GadgetText = GetCatalogStr(li.li_Catalog, MSG_MESSAGE_DELAY,"Message Delay:" );
// we run in English if there is a locale problem
resettime();
if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 39L)))
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open graphics.library V39+!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(GadToolsBase = (struct GfxBase *) OpenLibrary("gadtools.library", 0L)))
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open gadtools.library!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(ASLBase = (struct ASLBase *) OpenLibrary("asl.library", 38L)))
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open ASL.library V38+!\0", 24);
cleanexit(EXIT_FAILURE);
}
hero[BEOWULF ].control = HUMAN;
hero[BRUNHILD ].control = NONE;
hero[EGIL ].control = NONE;
hero[RAGNAR ].control = AMIGA;
hero[SIEGFRIED].control = NONE;
hero[STARKAD ].control = NONE;
ok = FALSE;
if (FileHandle = Open("PROGDIR:Saga.config", MODE_OLDFILE))
{ if (Read(FileHandle, IOBuffer, 21) == 21)
{ ok = TRUE;
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ hero[whichhero].control = (SLONG) ((SBYTE) IOBuffer[whichhero]);
}
DisplayID = (ULONG) ( (IOBuffer[ 6] * 16777216)
+ (IOBuffer[ 7] * 65536)
+ (IOBuffer[ 8] * 256)
+ IOBuffer[ 9] );
DisplayWidth = (ULONG) ( (IOBuffer[10] * 16777216)
+ (IOBuffer[11] * 65536)
+ (IOBuffer[12] * 256)
+ IOBuffer[13] );
DisplayHeight = (ULONG) ( (IOBuffer[14] * 16777216)
+ (IOBuffer[15] * 65536)
+ (IOBuffer[16] * 256)
+ IOBuffer[17] );
DisplayDepth = (UWORD) ( (IOBuffer[18] * 256)
+ IOBuffer[19] );
speed = (WORD) IOBuffer[20];
}
Close(FileHandle);
// FileHandle = NULL;
}
/* argument parsing */
if (argc) /* started from CLI */
{ if (!(ArgsPtr = ReadArgs
( "FILE",
(LONG *) args,
NULL
)))
{ strcpy(smrstring, GetCatalogStr(li.li_Catalog, MSG_USAGE, "Usage"));
strcat(smrstring, ": %s [[FILE=]<savedgame>]\n");
Printf(smrstring, argv[0]);
cleanexit(EXIT_FAILURE);
}
if (args[0])
{ strcpy(pathname, args[0]);
cliload = TRUE;
} }
strcpy(smrstring, "Saga: ");
strcat(smrstring, GetCatalogStr(li.li_Catalog, MSG_S_M_R, "Screen Mode Requester"));
if (!ok)
{ if (!(smr = (struct ScreenModeRequester *) AllocAslRequestTags
( ASL_ScreenModeRequest,
ASLSM_TitleText, smrstring,
ASLSM_InitialDisplayID, HIRES_KEY | PAL_MONITOR_ID | LACE,
ASLSM_InitialDisplayWidth, SCREENXPIXEL,
ASLSM_InitialDisplayHeight, SCREENYPIXEL,
ASLSM_InitialDisplayDepth, DEPTH,
ASLSM_DoWidth, TRUE,
ASLSM_DoHeight, TRUE,
ASLSM_DoDepth, TRUE,
ASLSM_MinWidth, SCREENXPIXEL,
ASLSM_MinHeight, SCREENYPIXEL,
ASLSM_MinDepth, DEPTH,
TAG_DONE
)))
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create ASL screen mode request!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (AslRequest(smr, 0L))
{ DisplayID = smr->sm_DisplayID;
DisplayWidth = smr->sm_DisplayWidth;
DisplayHeight = smr->sm_DisplayHeight;
DisplayDepth = smr->sm_DisplayDepth;
}
FreeAslRequest(smr);
}
ScreenPtr = (struct Screen *) OpenScreenTags
( NULL,
SA_Width, DisplayWidth,
SA_Height, DisplayHeight,
SA_Depth, DisplayDepth,
SA_DisplayID, DisplayID,
SA_Title, TITLEBAR,
SA_Font, &Topaz8,
SA_PubName, "SAGA",
SA_Colors32, table1,
SA_Pens, Pens,
SA_Interleaved, TRUE,
TAG_DONE
);
if (!ScreenPtr)
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open screen!\0", 24);
cleanexit(EXIT_FAILURE);
}
PubScreenStatus(ScreenPtr, NULL); // take the screen public
for (whichcountry = 36; whichcountry <= 65; whichcountry++)
{ SetRGB32(&ScreenPtr->ViewPort, 8 + whichcountry, 0x00000000, 0x00000000, 0x99999999);
}
LoadRGB32(&(ScreenPtr->ViewPort), table2);
/* GadTools */
if (!(VisualInfoPtr = (APTR) GetVisualInfo(ScreenPtr, TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't get GadTools visual info!\0", 24);
cleanexit(EXIT_FAILURE);
}
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ CycleGadget[whichhero].ng_VisualInfo = VisualInfoPtr;
}
SpeedGadget.ng_VisualInfo = VisualInfoPtr;
if (!(MenuPtr = (struct Menu *) CreateMenus(NewMenu, TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create menus!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(LayoutMenus(MenuPtr, VisualInfoPtr, TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't lay out menus!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(PrevGadgetPtr = (struct Gadget *) CreateContext(&GListPtr)))
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create GadTools context!\0", 24);
cleanexit(EXIT_FAILURE);
}
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ CycleGadgetPtr[whichhero] = PrevGadgetPtr = (struct Gadget *) CreateGadget
( CYCLE_KIND,
PrevGadgetPtr,
&CycleGadget[whichhero],
GTCY_Labels, CycleOptions,
GTCY_Active, hero[whichhero].control,
TAG_DONE
);
}
SpeedGadgetPtr = PrevGadgetPtr = (struct Gadget *) CreateGadget
( SLIDER_KIND,
PrevGadgetPtr,
&SpeedGadget,
GA_RelVerify, TRUE,
GTSL_Min, 0,
GTSL_Max, 4,
GTSL_Level, speed,
GT_Underscore, '_',
TAG_DONE
);
/* main window */
if (!(MainWindowPtr = (struct Window *) OpenWindowTags(NULL,
WA_Left, 0,
WA_Top, 11,
WA_Width, 640,
WA_Height, 501,
WA_IDCMP, IDCMP_RAWKEY
| IDCMP_VANILLAKEY
| IDCMP_MOUSEBUTTONS
| IDCMP_INTUITICKS
| IDCMP_CLOSEWINDOW
| IDCMP_REFRESHWINDOW
| IDCMP_MENUPICK
| IDCMP_MENUVERIFY
| CYCLEIDCMP,
WA_Flags, WFLG_BORDERLESS,
WA_Gadgets, GListPtr,
WA_CustomScreen, ScreenPtr,
WA_Activate, TRUE,
TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open window!\0", 24);
cleanexit(EXIT_FAILURE);
}
/* redirection of AmigaDOS system requesters */
OldWindowPtr = ProcessPtr->pr_WindowPtr;
ProcessPtr->pr_WindowPtr = (APTR) MainWindowPtr;
if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, "#?.saga", ASL_Window, MainWindowPtr, TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create ASL file request!\0", 24);
cleanexit(EXIT_FAILURE);
}
SetMenuStrip(MainWindowPtr, MenuPtr);
createcounters();
while (1)
{ titlescreen();
if (!loaded)
{ newgame();
}
gameloop();
} }
MODULE void gameloop(void)
{ SLONG countertype,
fastest,
strongest,
strongestjarl,
result,
whichhero,
whichjarl,
whichcountry,
whichmonster,
whichtreasure,
whichsord;
FLAG transfer;
do
{ strcpy(titlestring, TITLEBAR);
strcat(titlestring, ": ");
strcat(titlestring, GetCatalogStr(li.li_Catalog, MSG_TURN, "Turn"));
strcat(titlestring, " ");
stcl_d(numberstring, turn);
strcat(titlestring, numberstring);
strcat(titlestring, " ");
strcat(titlestring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
strcat(titlestring, " ");
stcl_d(numberstring, TURNS);
strcat(titlestring, numberstring);
SetWindowTitles(MainWindowPtr, (UBYTE *) -1, titlestring); // this is not copied, it is a pointer
strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_TURN, "Turn"));
strcat(saystring, " ");
stcl_d(numberstring, turn);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
strcat(saystring, " ");
stcl_d(numberstring, TURNS);
strcat(saystring, numberstring);
strcat(saystring, "...");
say(LOWER);
OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW, NOSUB));
OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE, NOSUB));
OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS, NOSUB));
result = getevent(KEYBOARD, NULL);
if (result == -4)
{ for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ hero[whichhero].alive = FALSE;
hero[whichhero].verydead = TRUE;
}
gameover = TRUE;
}
OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW, NOSUB));
OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE, NOSUB));
OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS, NOSUB));
if (!gameover)
{
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (!hero[whichhero].alive && !hero[whichhero].verydead)
{ transfer = FALSE;
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
{ transfer = TRUE;
break; // for speed
} }
if (hero[whichhero].control == AMIGA)
{ if (transfer)
{ strongest = fastest = 0;
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if
( jarl[whichjarl].alive
&& jarl[whichjarl].hero == whichhero
)
{ if (jarl[whichjarl].strength > strongest)
{ strongest = jarl[whichjarl].strength;
fastest = jarl[whichjarl].moves;
strongestjarl = whichjarl;
} elif (jarl[whichjarl].strength == strongest)
{ if (jarl[whichjarl].moves > fastest)
{ strongest = jarl[whichjarl].strength;
fastest = jarl[whichjarl].moves;
strongestjarl = whichjarl;
} } } }
promote(whichhero, strongestjarl);
strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_PROMOTES_JARL, "promotes jarl"));
strcat(saystring, " ");
strcat(saystring, jarl[strongestjarl].name);
strcat(saystring, " (");
stcl_d(numberstring, jarl[strongestjarl].strength);
strcat(saystring, numberstring);
strcat(saystring, "-");
stcl_d(numberstring, jarl[strongestjarl].moves);
strcat(saystring, numberstring);
strcat(saystring, ").");
say(LOWER);
anykey();
} else
{ withdraw(whichhero);
strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_WITHDRAWS_FROM_PLAY, "withdraws from play"));
strcat(saystring, ".");
say(LOWER);
anykey();
} }
elif (hero[whichhero].control == HUMAN)
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, ", (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_WITHDRAW, "W"));
strcat(saystring, ")");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_WITHDRAW, "ithdraw"));
strcat(saystring, "/(");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_RESTART, "R"));
strcat(saystring, ")");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_RESTART, "estart"));
if (transfer)
{ strcat(saystring, "/(");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_TRANSFER, "T"));
strcat(saystring, ")");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_TRANSFER, "ransfer"));
strcat(saystring, "?");
say(LOWER);
do
{ result = getevent(KEYBOARD, NULL);
} while (result != onekey[ONEKEY_WITHDRAW] && result != onekey[ONEKEY_RESTART] && result != onekey[ONEKEY_TRANSFER]);
if (result == onekey[ONEKEY_TRANSFER])
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, ", ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_W_J_T_P, "select which jarl to promote"));
strcat(saystring, "?");
say(LOWER);
do
{ whichjarl = getevent(COUNTER, &countertype);
} while
( whichjarl < 0
|| countertype != JARL
|| jarl[whichjarl].hero != whichhero
);
promote(whichhero, whichjarl);
} }
else
{ strcat(saystring, "?");
say(LOWER);
do
{ result = getevent(KEYBOARD, NULL);
} while (result != onekey[ONEKEY_WITHDRAW] && result != onekey[ONEKEY_RESTART]);
}
if (result == onekey[ONEKEY_WITHDRAW])
{ withdraw(whichhero);
} elif (result == onekey[ONEKEY_RESTART])
{ newhero(whichhero, FALSE);
} } } }
phase1(); // movement
phase2(); // combat
phase3(); // kingdoms
/* "4. PLACE MONSTERS. A number of monsters equal to the number
of heroes in play are randomly placed face up by rolling two dice
and placing the monster in the area indicated. (This is done every
turn until all counters are used. "Dead" monsters may not be
reused." */
place_monsters(); // phase 4
/* "5. PLACE jarls. A number of jarls equal to the number of
heroes in play are randomly placed face up by rolling two dice
and placing the jarl in the area indicated. (This is done every
turn until all counters are used. "Dead" jarls may not be
reused." */
place_jarls(); // phase 5
refreshcounters();
/* 6. MARK TURN. One turn is marked off. */
turn++;
}
} while (turn <= TURNS && !gameover);
/* "At the end of the 20th turn the game is over and players total
their glory to determine who has won. The turn should be marked off on
each player's record sheet." */
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ remove_hero(whichhero, FALSE);
}
for (whichjarl = 0; whichjarl <= JARL; whichjarl++)
{ remove_jarl(whichjarl, FALSE);
}
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ remove_monster(whichmonster, FALSE);
}
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ remove_treasure(whichtreasure, FALSE);
}
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ remove_sord(whichsord, FALSE);
}
refreshcounters();
for (whichcountry = 0; whichcountry <= 65; whichcountry++)
{ world[whichcountry].hero = -1;
}
if (!gameover)
{ SetAPen(MainWindowPtr->RPort, BLACK);
RectFill(MainWindowPtr->RPort, 0, 0, SCREENXPIXEL, SCREENYPIXEL);
strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_GAME_OVER, "Game over"));
strcat(saystring, "!");
say(LOWER);
SetDrMd(MainWindowPtr->RPort, JAM1);
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].control != NONE)
{ hero[whichhero].glory += hero[whichhero].wealth / 10;
hero[whichhero].glory += hero[whichhero].luck / 3;
if
( treasure[BROSUNGNECKLACE].possessortype == HERO
&& treasure[BROSUNGNECKLACE].possessor == whichhero
)
{ hero[whichhero].wealth += 20;
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
{ hero[whichhero].glory += jarl[whichjarl].strength / 2;
if
( treasure[BROSUNGNECKLACE].possessortype == JARL
&& treasure[BROSUNGNECKLACE].possessor == whichjarl
)
{ hero[whichhero].wealth += 20;
} } } }
if (hero[whichhero].control == NONE)
{ SetAPen(MainWindowPtr->RPort, MEDIUMGREY);
} elif (hero[whichhero].glory >= 15)
{ SetAPen(MainWindowPtr->RPort, GREEN);
} else
{ SetAPen(MainWindowPtr->RPort, RED);
}
RectFill(MainWindowPtr->RPort, 320 - 70, 200 + (whichhero * SCOREDISTANCE), 320 + 70, 200 + 11 + (whichhero * SCOREDISTANCE));
SetAPen(MainWindowPtr->RPort, BLACK);
Move(MainWindowPtr->RPort, 320 - 70 + 4, 200 + 8 + (whichhero * SCOREDISTANCE));
Text(MainWindowPtr->RPort, hero[whichhero].name, strlen(hero[whichhero].name));
if (hero[whichhero].control == NONE)
{ strcpy(numberstring, "-");
} else
{ stcl_d(numberstring, hero[whichhero].glory);
Move(MainWindowPtr->RPort, 320 + 70 - (8 * 4) - 4 + (8 * (4 - strlen(numberstring))), 200 + 8 + (whichhero * SCOREDISTANCE));
Text(MainWindowPtr->RPort, numberstring, strlen(numberstring));
} }
SetAPen(MainWindowPtr->RPort, BLACK);
Move(MainWindowPtr->RPort, 340, 200);
Draw(MainWindowPtr->RPort, 340, 200 + ((HEROES + 1) * SCOREDISTANCE));
clearkybd();
waitkey();
} }
MODULE void callforaid(SLONG passedtype, SLONG passed)
{ SLONG passedhero, passedwhere, whichjarl;
if (passedtype == HERO)
{ passedhero = passed;
passedwhere = hero[passed].where;
} else
{ // assert(passedtype == JARL);
// assert(jarl[passed].hero != -1);
passedhero = jarl[passed].hero;
passedwhere = jarl[passed].where;
}
if (passedtype == JARL && hero[passedhero].where == passedwhere)
{ hero[passedhero].defending = TRUE;
select_hero(passedhero, FALSE);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if
( jarl[whichjarl].hero == passedhero
&& jarl[whichjarl].where == passedwhere
&& !jarl[whichjarl].defending
)
{ jarl[whichjarl].defending = TRUE;
select_jarl(whichjarl, FALSE);
} }
refreshcounters();
}
MODULE void dobattle(SLONG defendtype, SLONG defender, SLONG attackhero)
{ SLONG decision,
result,
attackstrength = 0,
attackluck = 0,
attacktype,
attacker,
defendstrength = 0,
defendluck = 0,
defendhero,
whichhero,
whichjarl,
whichsord;
/* defendtype: type of defender, one of HERO, JARL, MONSTER or KINGDOM.
defender: ordinal number of defender. */
if (defendtype == HERO)
{ defendhero = defender;
hero[defender].defending = TRUE;
select_hero(defender, FALSE);
callforaid(HERO, defender);
} elif (defendtype == JARL)
{ defendhero = jarl[defender].hero;
jarl[defender].defending = TRUE;
if (defendhero != -1)
{ select_jarl(defender, FALSE);
callforaid(JARL, defender);
} else
{ select_jarl(defender, TRUE);
} }
elif (defendtype == MONSTER)
{ defendstrength = monster[defender].strength;
defendhero = -1;
} else
{ // assert(defendtype == KINGDOM);
defendstrength = world[defender].tax;
defendhero = -1; // even if it already has a king it makes no difference to the combat
}
// "II. ROLL FOR DROW, WITCH, OR GHOST MAGIC SPELLS (IF APPLICABLE)."
if (defendtype == MONSTER)
{ if (monster[defender].species == GHOST)
{ decision = d6();
if (decision <= 3)
{ cast(defender, decision);
} }
elif (monster[defender].species == DROW)
{ cast(defender, d6());
} elif (monster[defender].species == WITCH)
{ cast(defender, d6());
if (attackersleft())
{ cast(defender, d6());
} } }
if (!attackersleft())
{ // no attackers, abort combat
return;
}
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].attacking)
{ attackstrength += hero[whichhero].strength;
} elif (hero[whichhero].defending)
{ defendstrength += hero[whichhero].strength;
} }
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ attackstrength += jarl[whichjarl].strength;
} elif (jarl[whichjarl].defending)
{ defendstrength += jarl[whichjarl].strength;
} }
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].attacking && hero[whichhero].hagall)
{ attackstrength--;
} elif (hero[whichhero].defending && hero[whichhero].hagall)
{ defendstrength--;
} }
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking && jarl[whichjarl].hagall)
{ attackstrength--;
} elif (jarl[whichjarl].defending && jarl[whichjarl].hagall)
{ defendstrength--;
} }
if (defendtype == MONSTER && monster[defender].hagall)
{ defendstrength--;
}
/* "III. MODIFY THE DIE ROLL WITH LUCK. Before the die is rolled,
heroes who are involved in the battle (or who have jarls involved in
the battle) may modify the die roll up or down one with each point of
luck expended before the die is rolled. If there are two or more
heroes involved in the battle they should each write how much luck
they are using to modify the die roll and how before revealing the
amounts simultaneously." */
if (hero[attackhero].luck >= 1)
{ if (hero[attackhero].control == HUMAN)
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKING, "Attacking"));
saywho(HERO, attackhero, FALSE, TRUE);
strcat(saystring, ", ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USE_LUCK, "use luck"));
strcat(saystring, " (0-");
if (hero[attackhero].luck >= 9)
{ strcat(saystring, "9");
} else
{ stcl_d(numberstring, hero[attackhero].luck);
strcat(saystring, numberstring);
}
strcat(saystring, ")?");
say(LOWER);
attackstrength += getluck(attackhero);
} else
{ // assert(hero[attackhero].control == AMIGA);
attackluck = 0;
} }
if (defendhero != -1)
{ if (hero[defendhero].control == HUMAN)
{ if (hero[defendhero].luck >= 1)
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDING, "Defending"));
saywho(defendtype, defender, FALSE, TRUE);
strcat(saystring, ", ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USE_LUCK, "use luck"));
strcat(saystring, " (0-");
if (hero[defendhero].luck >= 9)
{ strcat(saystring, "9");
} else
{ stcl_d(numberstring, hero[defendhero].luck);
strcat(saystring, numberstring);
}
strcat(saystring, ")?");
say(LOWER);
defendstrength += getluck(defendhero);
} }
else
{ // assert(hero[defendhero].control == AMIGA);
defendluck = 0;
} }
/* if (hero[attackhero].control == AMIGA && attackluck > 0)
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKING, "Attacking"));
saywho(HERO, attackhero, FALSE, TRUE);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USED, "used"));
strcat(saystring, " ");
stcl_d(numberstring, attackluck);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LUCK2, "luck"));
strcat(saystring, ".");
say(LOWER);
anykey();
}
if (defendhero != -1)
{ if (hero[defendhero].control == AMIGA && defendluck > 0)
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDING, "Defending"));
saywho(HERO, defendhero, FALSE, TRUE);
strcat(saystring, ", ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USED, "used"));
strcat(saystring, " ");
stcl_d(numberstring, defendluck);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LUCK2, "luck"));
strcat(saystring, ".");
say(LOWER);
anykey();
} } */
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].alive && hero[whichhero].rune == OGAL)
{ if (hero[whichhero].attacking)
{ attackstrength++;
} elif (hero[whichhero].defending)
{ defendstrength++;
} } }
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if
( ( sord[whichsord].possessortype == HERO
&& hero[sord[whichsord].possessor].attacking
)
|| ( sord[whichsord].possessortype == JARL
&& jarl[sord[whichsord].possessor].attacking
) )
{ if (whichsord == BALMUNG || whichsord == HRUNTING)
{ attackstrength++;
} elif (whichsord == DRAGVENDILL || whichsord == GRAM || whichsord == TYRFING)
{ attackstrength += 2;
} elif (whichsord == LOVI)
{ attackstrength++;
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].defending)
{ attackstrength += 2;
break;
} } } }
elif
( ( sord[whichsord].possessortype == HERO
&& hero[sord[whichsord].possessor].defending
)
|| ( sord[whichsord].possessortype == JARL
&& jarl[sord[whichsord].possessor].defending
) )
{ if (whichsord == BALMUNG || whichsord == HRUNTING)
{ defendstrength++;
} elif (whichsord == DRAGVENDILL || whichsord == GRAM || whichsord == TYRFING)
{ defendstrength += 2;
} elif (whichsord == LOVI)
{ defendstrength++;
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ defendstrength += 2;
break;
} } } } }
if (hero[attackhero].attacking)
{ attackstrength += odin_tyr(attackhero, TRUE);
if (attackstrength < 0)
{ attackstrength = 0;
} }
if (defendhero != -1 && hero[defendhero].defending)
{ defendstrength += odin_tyr(defendhero, FALSE);
if (defendstrength < 0)
{ defendstrength = 0;
} }
if
( ( sord[BALMUNG].possessortype == HERO
&& hero[sord[BALMUNG].possessor].attacking
)
|| ( sord[BALMUNG].possessortype == JARL
&& jarl[sord[BALMUNG].possessor].attacking
) )
{ ; // one of the attackers is wielding Balmung
// assert(sord[BALMUNG].where == -1);
} else
{ if
( ( treasure[MAGICSHIRT].possessortype == HERO
&& hero[treasure[MAGICSHIRT].possessor].defending
)
|| ( treasure[MAGICSHIRT].possessortype == JARL
&& jarl[treasure[MAGICSHIRT].possessor].defending
) )
{ // one of the defenders is wearing the Magic Shirt
// assert(treasure[MAGICSHIRT].where == -1);
defendstrength++;
}
if
( ( treasure[MAILCOAT].possessortype == HERO
&& hero[treasure[MAILCOAT].possessor].defending
)
|| ( treasure[MAILCOAT].possessortype == JARL
&& jarl[treasure[MAILCOAT].possessor].defending
) )
{ // one of the defenders is wearing the Mail Coat
// assert(treasure[MAILCOAT].where == -1);
defendstrength += 2;
} }
/* "V. ROLL ONE DIE AND CHECK THE COMBAT RESULTS TABLE TO DETERMINE
THE OUTCOME OF THE BATTLE AFTER ADDING ALL MODIFIERS TO THE DIE ROLL.
After all modifications to the combat strengths of both sides have
been made, subtract the defender's strength from the attacker's and
consult the COMBAT RESULTS TABLE below to determine the results
according to a die roll and modifications due to luck." */
/*
Printf("Involved in the combat are:\n");
Printf(" Attackers:\n");
if (hero[attackhero].attacking)
{ Printf(" Hero %s!\n", hero[attackhero].name);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ Printf(" Jarl %s!\n", jarl[whichjarl].name);
} }
Printf(" Defenders:\n");
if (defendhero != -1)
{ if (hero[defendhero].defending)
{ Printf(" Hero %s!\n", hero[defendhero].name);
} }
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].defending)
{ Printf(" Jarl %s!\n", jarl[whichjarl].name);
} }
if (defendhero == -1)
{ if (defendtype == KINGDOM)
{ Printf(" Kingdom %s!\n", world[defender].name);
} elif (defendtype == MONSTER)
{ Printf(" Monster %s!\n", monster[defender].name);
} }
*/
result = attackstrength - defendstrength + d6();
if (result == 4) // attacker flees
{ if (sord[HRUNTING].possessortype == HERO)
{ if (hero[sord[HRUNTING].possessor].attacking)
{ result = 6; // defender flees
} }
elif (sord[HRUNTING].possessortype == JARL)
{ if (jarl[sord[HRUNTING].possessor].attacking)
{ result = 6; // defender flees
} } }
elif (result == 6) // defender flees
{ if (sord[HRUNTING].possessortype == HERO)
{ if (hero[sord[HRUNTING].possessor].defending)
{ result = 4; // attacker flees
} }
elif (sord[HRUNTING].possessortype == JARL)
{ if (jarl[sord[HRUNTING].possessor].defending)
{ result = 4; // attacker flees
} } }
/* "VI. APPLY THE COMBAT RESULT." */
if (hero[attackhero].attacking)
{ attacktype = HERO;
attacker = attackhero;
} else
{ attacktype = JARL; // uses the first jarl found
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ attacker = whichjarl;
break;
} } }
if (result <= 2) // attackers killed
{ if (hero[attackhero].attacking)
{ kill(defendtype, defender, defendhero, HERO, attackhero, attackhero);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ kill(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
} } }
elif (result == 3) // attackers wounded
{ if (hero[attackhero].attacking)
{ wound(defendtype, defender, defendhero, HERO, attackhero, attackhero);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ wound(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
} } }
elif (result == 4) // attackers flee
{ if (hero[attackhero].attacking)
{ flee(defendtype, defender, defendhero, HERO, attackhero, attackhero);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ flee(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
} } }
elif (result == 5) // no result
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_NO_RESULT, "No result"));
strcat(saystring, ".");
say(LOWER);
anykey();
} elif (result == 6) // defenders flee
{ if (defendtype == MONSTER || defendtype == KINGDOM)
{ flee(attacktype, attacker, attackhero, defendtype, defender, -1);
} else
{ assert(defendtype == HERO || defendtype == JARL);
if (defendhero != -1 && hero[defendhero].defending)
{ flee(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].defending)
{ flee(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
} } } }
elif (result == 7) // defenders wounded
{ if (defendtype == MONSTER || defendtype == KINGDOM)
{ wound(attacktype, attacker, attackhero, defendtype, defender, -1);
} else
{ assert(defendtype == HERO || defendtype == JARL);
if (defendhero != -1 && hero[defendhero].defending)
{ wound(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].defending)
{ wound(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
} } } }
else // defenders killed
{ // assert(result >= 8);
if (defendtype == MONSTER || defendtype == KINGDOM)
{ kill(attacktype, attacker, attackhero, defendtype, defender, -1);
} else
{ assert(defendtype == HERO || defendtype == JARL);
if (defendhero != -1 && hero[defendhero].defending)
{ kill(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].defending)
{ kill(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
} } } }
if (hero[attackhero].attacking)
{ thor(attackhero);
}
if (defendhero != -1 && hero[defendhero].defending && hero[defendhero].alive)
{ thor(defendhero);
}
if (hero[attackhero].attacking)
{ pray(attackhero);
}
if (defendhero != -1 && hero[defendhero].defending && hero[defendhero].alive)
{ pray(defendhero);
}
if (hero[attackhero].attacking)
{ deselect_hero(attackhero, FALSE);
hero[attackhero].attacking = FALSE;
} elif (hero[defendhero].defending)
{ deselect_hero(defendhero, FALSE);
hero[defendhero].defending = FALSE;
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ deselect_jarl(whichjarl, FALSE);
jarl[whichjarl].attacking =
jarl[whichjarl].recruitable = FALSE;
} elif (jarl[whichjarl].defending)
{ deselect_jarl(whichjarl, FALSE);
jarl[whichjarl].defending =
jarl[whichjarl].recruitable = FALSE;
} }
refreshcounters();
}
MODULE void flee(SLONG routertype, SLONG router, SLONG routerhero, SLONG routedtype, SLONG routed, SLONG routedhero)
{ if (routedtype == HERO)
{ hero[routed].glory -= 2;
if (hero[routed].glory < 0)
{ hero[routed].glory = 0;
} }
if (routertype == HERO || routertype == JARL)
{ if (routedtype == KINGDOM)
{ world[routed].hero = routerhero;
darken();
saywho(routertype, router, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_CONQUERED_KINGDOM, "has conquered kingdom"));
strcat(saystring, " ");
strcat(saystring, world[routed].name);
strcat(saystring, " (");
stcl_d(numberstring, world[routed].tax);
strcat(saystring, numberstring);
strcat(saystring, ").");
say(LOWER);
anykey();
} elif (routedtype == JARL)
{ if
( routerhero != -1
&& hero[routerhero].where == jarl[routed].where
&& !recruit(routed, routerhero)
)
{ saywho(JARL, routed, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
strcat(saystring, "!");
say(LOWER);
anykey();
if (routertype == HERO)
{ if (hero[router].control == AMIGA)
{ amiga_rout(JARL, routed);
} else
{ // assert(hero[router].control == HUMAN);
human_rout(JARL, routed, routerhero);
} }
else
{ // assert(routertype == JARL);
if (jarl[router].hero == -1 || hero[jarl[router].hero].control == AMIGA)
{ amiga_rout(JARL, routed);
} else
{ human_rout(JARL, routed, routerhero);
} } } }
elif (routedtype == HERO)
{ saywho(HERO, routed, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
strcat(saystring, "!");
say(LOWER);
anykey();
if (routertype == HERO)
{ if (hero[router].control == AMIGA)
{ amiga_rout(HERO, routed);
} else
{ // assert(hero[router].control == HUMAN);
human_rout(HERO, routed, routerhero);
} }
else
{ // assert(routertype == JARL);
if (jarl[router].hero == -1 || hero[jarl[router].hero].control == AMIGA)
{ amiga_rout(HERO, routed);
} else
{ human_rout(HERO, routed, routerhero);
} } }
elif (routedtype == MONSTER)
{ strcpy(saystring, monstertypes[monster[routed].species]);
strcat(saystring, " ");
strcat(saystring, monster[routed].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
strcat(saystring, "!");
say(LOWER);
anykey();
if (routertype == HERO)
{ if (hero[router].control == AMIGA)
{ amiga_rout(MONSTER, routed);
} else
{ // assert(hero[router].control == HUMAN);
human_rout(MONSTER, routed, routerhero);
} }
else
{ // assert(routertype == JARL);
if (jarl[router].hero == -1 || hero[jarl[router].hero].control == AMIGA)
{ amiga_rout(MONSTER, routed);
} else
{ human_rout(MONSTER, routed, routerhero);
} } } }
else
{ // assert(routertype == MONSTER || routertype == KINGDOM);
if (routedtype == JARL)
{ saywho(JARL, routed, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
strcat(saystring, "!");
say(LOWER);
anykey();
amiga_rout(JARL, routed);
} elif (routedtype == HERO)
{ saywho(HERO, routed, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
strcat(saystring, "!");
say(LOWER);
anykey();
amiga_rout(HERO, routed);
} } }
MODULE void wound(SLONG woundertype, SLONG wounder, SLONG wounderhero, SLONG woundedtype, SLONG wounded, SLONG woundedhero)
{ SLONG glory = 0, luck = 0, whichtreasure, whichsord;
/* WOUNDED. Heroes on the wounded side are wounded.
Jarls on the wounded side are removed from the board and placed,
upside down, in their respective piles, from which they will reenter
play normally. There is no further effect from being wounded, except
that jarls that reenter play after being wounded are to be considered
unrecruited jarls. */
if (woundedtype == HERO)
{ if (hero[wounded].wounded)
{ kill(woundertype, wounder, wounderhero, woundedtype, wounded, woundedhero);
return;
}
hero[wounded].wounded = TRUE;
saywho(HERO, wounded, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_WOUNDED, "is wounded"));
strcat(saystring, "!");
say(LOWER);
anykey();
if (hero[wounded].maidens)
{ hero[wounded].maidens--;
hero[wounded].wounded = FALSE;
strcpy(saystring, "Frey ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SENDS_A_MAIDEN_TO_HEAL_HERO, "Frey sends a maiden to heal hero"));
strcat(saystring, " ");
strcat(saystring, hero[wounded].name);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_WOUND, "'s wound"));
strcat(saystring, ".");
say(LOWER);
anykey();
}
if (wounderhero != -1)
{ gain(wounderhero, hero[woundedhero].strength / 2 / 2, hero[woundedhero].strength / 2 / 2);
} }
elif (woundedtype == JARL)
{ if
( wounderhero != -1
&& hero[wounderhero].where == jarl[wounded].where
&& recruit(wounded, wounderhero)
)
{ return;
}
jarl[wounded].alive = FALSE;
jarl[wounded].taken = FALSE;
jarl[wounded].hero = -1;
jarl[wounded].wealth = 0; // this is actually an ambiguity in the rules
remove_jarl(wounded, TRUE);
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if
( treasure[whichtreasure].possessortype == JARL
&& treasure[whichtreasure].possessor == wounded
)
{ // drop the treasure
treasure[whichtreasure].possessortype = KINGDOM;
treasure[whichtreasure].possessor = -1;
treasure[whichtreasure].where = jarl[wounded].where;
move_treasure(whichtreasure, TRUE);
} }
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if
( sord[whichsord].possessortype == JARL
&& sord[whichsord].possessor == wounded
)
{ // drop the sword
sord[whichsord].possessortype = KINGDOM;
sord[whichsord].possessor = -1;
sord[whichsord].where = jarl[wounded].where;
move_sord(whichsord, TRUE);
} }
saywho(JARL, wounded, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_WOUNDED, "is wounded"));
strcat(saystring, "!");
say(LOWER);
anykey();
if (wounderhero != -1)
{ gain(wounderhero, jarl[wounded].strength / 2 / 2, jarl[wounded].strength / 2 / 2); // not the same as / 4 due to rounding
} }
elif (woundedtype == KINGDOM)
{ world[wounded].hero = wounderhero;
darken();
saywho(woundertype, wounder, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_CONQUERED_KINGDOM, "has conquered kingdom"));
strcat(saystring, " ");
strcat(saystring, world[wounded].name);
strcat(saystring, " (");
stcl_d(numberstring, world[wounded].tax);
strcat(saystring, numberstring);
strcat(saystring, ").");
say(LOWER);
anykey();
} elif (woundedtype == MONSTER)
{ monster[wounded].alive = FALSE;
monster[wounded].taken = FALSE;
remove_monster(wounded, TRUE);
strcpy(saystring, monstertypes[monster[wounded].species]);
strcat(saystring, " ");
strcat(saystring, monster[wounded].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_WOUNDED, "is wounded"));
strcat(saystring, "!");
say(LOWER);
anykey();
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if
( treasure[whichtreasure].possessortype == MONSTER
&& treasure[whichtreasure].possessor == wounded
)
{ // give the treasure to the wounder of the dragon
// assert(monster[wounded].species == DRAGON);
treasure[whichtreasure].possessortype = woundertype;
treasure[whichtreasure].possessor = wounder;
treasure[whichtreasure].where = -1;
saywho(woundertype, wounder, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS_THE, "finds the"));
strcat(saystring, " ");
strcat(saystring, treasure[whichtreasure].name);
strcat(saystring, ".");
say(LOWER);
anykey();
} }
if (monster[wounded].wealth > 0)
{ hero[wounderhero].wealth += monster[wounded].wealth;
saywho(woundertype, wounder, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS, "finds"));
strcat(saystring, " ");
stcl_d(numberstring, monster[wounded].wealth);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
strcat(saystring, ".");
say(LOWER);
anykey();
}
switch (monster[wounded].species)
{
case DRAGON:
glory = 6;
luck = 5;
break;
case DROW:
glory = 3;
luck = 2;
break;
case GHOST:
glory = 2;
luck = 2;
break;
case GIANT:
glory = 4;
luck = 3;
break;
case TROLL:
glory = 3;
luck = 3;
break;
case WITCH:
glory = 5;
luck = 4;
break;
default:
// assert(0);
break;
}
glory /= 2;
luck /= 2;
// assert(wounderhero != -1);
gain(wounderhero, glory, luck);
} }
MODULE void kill(SLONG killertype, SLONG killer, SLONG killerhero, SLONG killedtype, SLONG killed, SLONG killedhero)
{ SLONG glory = 0, luck = 0, result, whichjarl, whichtreasure, whichsord;
if (killedtype == HERO)
{ hero[killed].alive =
hero[killed].attacking =
hero[killed].defending = FALSE;
remove_hero(killed, TRUE);
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if
( treasure[whichtreasure].possessortype == HERO
&& treasure[whichtreasure].possessor == killed
)
{ // drop the treasure
treasure[whichtreasure].possessortype = KINGDOM;
treasure[whichtreasure].possessor = -1;
treasure[whichtreasure].where = hero[killed].where;
move_treasure(whichtreasure, TRUE);
} }
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if
( sord[whichsord].possessortype == HERO
&& sord[whichsord].possessor == killed
)
{ // drop the sword
sord[whichsord].possessortype = KINGDOM;
sord[whichsord].possessor = -1;
sord[whichsord].where = hero[killed].where;
move_sord(whichsord, TRUE);
} }
saywho(HERO, killed, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
strcat(saystring, "!");
say(LOWER);
anykey();
if (killerhero != -1)
{ gain(killerhero, hero[killedhero].strength / 2, hero[killedhero].strength / 2);
} }
elif (killedtype == JARL)
{ if
( killerhero == -1
|| hero[killerhero].where != jarl[killed].where
|| !recruit(killed, killerhero)
)
{ jarl[killed].alive =
jarl[killed].attacking =
jarl[killed].defending = FALSE;
remove_jarl(killed, TRUE);
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if
( treasure[whichtreasure].possessortype == JARL
&& treasure[whichtreasure].possessor == killed
)
{ // drop the treasure
treasure[whichtreasure].possessortype = KINGDOM;
treasure[whichtreasure].possessor = -1;
treasure[whichtreasure].where = jarl[killed].where;
move_treasure(whichtreasure, TRUE);
} }
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if
( sord[whichsord].possessortype == JARL
&& sord[whichsord].possessor == killed
)
{ // drop the treasure
sord[whichsord].possessortype = KINGDOM;
sord[whichsord].possessor = -1;
sord[whichsord].where = jarl[killed].where;
move_sord(whichsord, TRUE);
} }
saywho(JARL, killed, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
strcat(saystring, "!");
say(LOWER);
anykey();
if (killerhero != -1 && killedtype == JARL)
{ if (hero[killerhero].where == jarl[killed].where)
{ if (jarl[killed].wealth)
{ hero[killerhero].wealth += jarl[killed].wealth;
saywho(HERO, killerhero, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"));
strcat(saystring, " ");
stcl_d(numberstring, jarl[killed].wealth);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FROM, "from"));
strcat(saystring, " ");
saywho(JARL, killed, FALSE, TRUE);
strcat(saystring, ".");
say(LOWER);
anykey();
} }
else
{ for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if
( jarl[whichjarl].alive
&& jarl[whichjarl].hero == killerhero
&& jarl[whichjarl].where == jarl[killed].where
)
{ assert(whichjarl != killed);
if (jarl[killed].wealth)
{ jarl[whichjarl].wealth += jarl[killed].wealth;
saywho(JARL, whichjarl, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"));
strcat(saystring, " ");
stcl_d(numberstring, jarl[killed].wealth);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FROM, "from"));
strcat(saystring, " ");
saywho(JARL, killed, FALSE, TRUE);
strcat(saystring, ".");
say(LOWER);
anykey();
} } } } }
if (killedhero != -1)
{ if (hero[killedhero].control == HUMAN)
{ saywho(HERO, killedhero, TRUE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LOSE, "lose"));
strcat(saystring, " ");
stcl_d(numberstring, jarl[killed].strength / 2);
strcat(saystring, numberstring);
strcat(saystring, " (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_GLORY, "G"));
strcat(saystring, ")");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_GLORY, "lory"));
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OR, "or"));
strcat(saystring, " ");
stcl_d(numberstring, jarl[killed].strength / 2);
strcat(saystring, numberstring);
strcat(saystring, " (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_LUCK, "L"));
strcat(saystring, ")");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_LUCK, "uck"));
strcat(saystring, "?");
say(LOWER);
do
{ result = getevent(KEYBOARD, NULL);
} while (result != onekey[ONEKEY_GLORY] && result != onekey[ONEKEY_LUCK]);
if (result == onekey[ONEKEY_GLORY])
{ hero[killedhero].glory -= jarl[killed].strength / 2;
if (hero[killedhero].glory < 0)
{ hero[killedhero].glory = 0;
} }
else
{ // assert(result == onekey[ONEKEY_LUCK]);
hero[killedhero].luck -= jarl[killed].strength / 2;
if (hero[killedhero].luck < 0)
{ hero[killedhero].luck = 0;
} } }
else
{ // assert(hero[killedhero].control == AMIGA);
hero[killedhero].glory -= jarl[killed].strength / 2;
if (hero[killedhero].glory < 0)
{ hero[killedhero].glory = 0;
} } }
if (killerhero != -1)
{ gain(killerhero, jarl[killed].strength / 2, jarl[killed].strength / 2);
} } }
elif (killedtype == KINGDOM)
{ world[killed].hero = killerhero;
darken();
saywho(HERO, killerhero, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_CONQUERED_KINGDOM, "has conquered kingdom"));
strcat(saystring, " ");
strcat(saystring, world[killed].name);
strcat(saystring, " (");
stcl_d(numberstring, world[killed].tax);
strcat(saystring, numberstring);
strcat(saystring, ").");
say(LOWER);
anykey();
} elif (killedtype == MONSTER)
{ monster[killed].alive = FALSE;
remove_monster(killed, TRUE);
strcpy(saystring, monstertypes[monster[killed].species]);
strcat(saystring, " ");
strcat(saystring, monster[killed].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
strcat(saystring, "!");
say(LOWER);
anykey();
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if
( treasure[whichtreasure].possessortype == MONSTER
&& treasure[whichtreasure].possessor == killed
)
{ // give the treasure to the killer of the dragon
// assert(monster[killed].species == DRAGON);
treasure[whichtreasure].possessortype = killertype;
treasure[whichtreasure].possessor = killer;
treasure[whichtreasure].where = -1;
saywho(killertype, killer, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS_THE, "finds the"));
strcat(saystring, " ");
strcat(saystring, treasure[whichtreasure].name);
strcat(saystring, ".");
say(LOWER);
anykey();
} }
if (monster[killed].wealth > 0)
{ hero[killerhero].wealth += monster[killed].wealth;
saywho(killertype, killer, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS, "finds"));
strcat(saystring, " ");
stcl_d(numberstring, monster[killed].wealth);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
strcat(saystring, ".");
say(LOWER);
anykey();
}
switch (monster[killed].species)
{
case DRAGON:
glory = 6;
luck = 5;
break;
case DROW:
glory = 3;
luck = 2;
break;
case GHOST:
glory = 2;
luck = 2;
break;
case GIANT:
glory = 4;
luck = 3;
break;
case TROLL:
glory = 3;
luck = 3;
break;
case WITCH:
glory = 5;
luck = 4;
break;
default:
// assert(0);
break;
}
// assert(killerhero != -1);
gain(killerhero, glory, luck);
// check if hero was present at the combat
if
( killerhero != -1
&& hero[killerhero].attacking
)
{ if
( ( monster[killed].species == DROW
|| monster[killed].species == GHOST
|| monster[killed].species == WITCH
)
&& hero[killer].rune == -1
)
{ hero[killer].rune = rand() % (RUNES + 1);
saywho(HERO, killer, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LEARNS_THE_RUNE, "learns the rune"));
strcat(saystring, " ");
strcat(saystring, runename[hero[killer].rune]);
strcat(saystring, ", ");
strcat(saystring, runedesc[hero[killer].rune]);
strcat(saystring, ".");
say(LOWER);
anykey();
} } } }
MODULE FLAG recruit(SLONG recruited, SLONG recruiterhero)
{ SLONG jarls = 0,
result,
whichjarl;
if (jarl[recruited].hero == -1 && hero[recruiterhero].luck >= 1 && jarl[recruited].recruitable)
{ jarl[recruited].recruitable = FALSE;
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].hero == recruiterhero)
{ jarls++;
} }
if (jarls <= 3)
{ if (hero[recruiterhero].control == HUMAN)
{ saywho(HERO, recruiterhero, TRUE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RECRUIT_JARL, "recruit jarl"));
strcat(saystring, " ");
strcat(saystring, jarl[recruited].name);
strcat(saystring, " (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
strcat(saystring, "/");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
strcat(saystring, ")?");
say(LOWER);
do
{ result = getevent(KEYBOARD, NULL);
} while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
if (result == onekey[ONEKEY_YES])
{ hero[recruiterhero].luck--;
gain(recruiterhero, jarl[recruited].strength / 2, jarl[recruited].strength / 2);
jarl[recruited].hero = recruiterhero;
return(TRUE);
} else
{ // assert(result == onekey[ONEKEY_NO]);
} }
else
{ // assert(hero[recruiterhero].control == AMIGA);
hero[recruiterhero].luck--;
gain(recruiterhero, jarl[recruited].strength / 2, jarl[recruited].strength / 2);
jarl[recruited].hero = recruiterhero;
saywho(HERO, recruiterhero, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RECRUITS_JARL, "recruits jarl"));
strcat(saystring, " ");
strcat(saystring, jarl[recruited].name);
strcat(saystring, ".");
say(LOWER);
anykey();
return(TRUE);
} } }
return(FALSE);
}
MODULE SLONG d6(void)
{ return((rand() % 6) + 1);
}
AGLOBAL void cleanexit(SLONG rc)
{ BPTR FileHandle /* = NULL */ ;
SLONG whichhero;
destroycounters();
if (ASLRqPtr)
{ FreeAslRequest(ASLRqPtr);
ASLRqPtr = NULL;
}
if (OldWindowPtr)
{ ProcessPtr->pr_WindowPtr = OldWindowPtr;
}
/* It does not matter whether there are outstanding messages for a
window when it is closed, provided that the window does not use a
shared IDCMP message port. */
if (HelpWindowPtr)
{ CloseWindow(HelpWindowPtr);
HelpWindowPtr = NULL;
}
if (MainWindowPtr)
{ ClearMenuStrip(MainWindowPtr);
CloseWindow(MainWindowPtr);
MainWindowPtr = NULL;
}
if (GListPtr)
{ FreeGadgets(GListPtr);
GListPtr = NULL;
}
if (MenuPtr)
{ FreeMenus(MenuPtr);
MenuPtr = NULL;
}
if (VisualInfoPtr)
{ FreeVisualInfo(VisualInfoPtr);
VisualInfoPtr = NULL;
}
if (ScreenPtr)
{ CloseScreen(ScreenPtr);
ScreenPtr = NULL;
}
if (ASLBase)
{ CloseLibrary((struct Library *) ASLBase);
ASLBase = NULL;
}
if (GadToolsBase)
{ CloseLibrary((struct Library *) GadToolsBase);
GadToolsBase = NULL;
}
if (GfxBase)
{ CloseLibrary((struct Library *) GfxBase);
GfxBase = NULL;
}
if (LocaleBase)
{ CloseCatalog(li.li_Catalog);
CloseLibrary((struct Library *) LocaleBase);
LocaleBase = NULL;
}
if (IntuitionBase)
{ OpenWorkBench();
CloseLibrary((struct Library *) IntuitionBase);
IntuitionBase = NULL;
}
if (ArgsPtr)
{ FreeArgs(ArgsPtr);
ArgsPtr = NULL;
}
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ IOBuffer[whichhero] = (SBYTE) hero[whichhero].control;
}
IOBuffer[ 6] = (UBYTE) (DisplayID / 16777216);
IOBuffer[ 7] = (UBYTE) ((DisplayID % 16777216) / 65536);
IOBuffer[ 8] = (UBYTE) (((DisplayID % 16777216) % 65536) / 256);
IOBuffer[ 9] = (UBYTE) (((DisplayID % 16777216) % 65536) % 256);
IOBuffer[10] = (UBYTE) (DisplayWidth / 16777216);
IOBuffer[11] = (UBYTE) ((DisplayWidth % 16777216) / 65536);
IOBuffer[12] = (UBYTE) (((DisplayWidth % 16777216) % 65536) / 256);
IOBuffer[13] = (UBYTE) (((DisplayWidth % 16777216) % 65536) % 256);
IOBuffer[14] = (UBYTE) (DisplayHeight / 16777216);
IOBuffer[15] = (UBYTE) ((DisplayHeight % 16777216) / 65536);
IOBuffer[16] = (UBYTE) (((DisplayHeight % 16777216) % 65536) / 256);
IOBuffer[17] = (UBYTE) (((DisplayHeight % 16777216) % 65536) % 256);
IOBuffer[18] = (UBYTE) (DisplayDepth / 65536);
IOBuffer[19] = (UBYTE) (DisplayDepth % 65536);
IOBuffer[20] = (UBYTE) speed;
if (FileHandle = Open("PROGDIR:Saga.config", MODE_NEWFILE))
{ Write(FileHandle, IOBuffer, 21);
Close(FileHandle);
// FileHandle = NULL;
}
exit(rc); // End of program.
}
MODULE void say(SLONG position)
{ SLONG length;
length = strlen(saystring);
SetAPen(MainWindowPtr->RPort, BLACK);
if (position == UPPER)
{ RectFill
( MainWindowPtr->RPort,
0, MESSAGEY,
639, MESSAGEY + 7
);
Move(MainWindowPtr->RPort, 4, MESSAGEY + 6);
}
else
{ // assert(position == LOWER);
RectFill
( MainWindowPtr->RPort,
0, MESSAGEY + 10,
639, MESSAGEY + 27
);
Move(MainWindowPtr->RPort, 4, MESSAGEY + 16);
}
SetAPen(MainWindowPtr->RPort, WHITE);
if (position == LOWER && length > 79)
{ Text(MainWindowPtr->RPort, saystring, 79);
Move(MainWindowPtr->RPort, 4, MESSAGEY + 26);
Text(MainWindowPtr->RPort, &saystring[79], length - 79);
} else
{ Text(MainWindowPtr->RPort, saystring, length);
} }
MODULE void newhero(SLONG whichhero, FLAG givesord)
{ SLONG whichjarl, whichsord;
hero[whichhero].where =
hero[whichhero].homewhere = rand() % 36;
hero[whichhero].glory =
hero[whichhero].wealth = 0;
hero[whichhero].luck = 3;
hero[whichhero].alive = TRUE;
hero[whichhero].verydead =
hero[whichhero].wounded =
hero[whichhero].hagall =
hero[whichhero].loseturn = FALSE;
hero[whichhero].rune =
hero[whichhero].god = -1;
hero[whichhero].sea = NORMAL;
hero[whichhero].maidens = 0;
if (givesord)
{ hero[whichhero].promoted = -1;
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].hero == whichhero)
{ jarl[whichjarl].hero = -1;
} }
deselect_hero(whichhero, FALSE);
move_hero(whichhero, TRUE);
// we don't unslot newborn counters
if (!givesord)
{ return;
}
// at least one sword should should always be available
do
{ whichsord = rand() % 6;
} while (sord[whichsord].taken);
sord[whichsord].taken = TRUE;
sord[whichsord].possessortype = HERO;
sord[whichsord].possessor = whichhero;
sord[whichsord].where = -1;
}
MODULE SLONG getevent(SLONG mode, SLONG* countertype)
{ AUTO UWORD code,
qual;
AUTO ULONG class;
AUTO struct IntuiMessage* MsgPtr;
AUTO LONG country;
AUTO SLONG counter,
ticks = 0;
AUTO WORD mousex, mousey;
AUTO struct MenuItem* ItemPtr;
PERSIST SLONG cheat = 0;
/* return codes:
-4: Escape
-3: spacebar
-2: backspace
-1: invalid country */
while(1)
{ while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
mousex = MsgPtr->MouseX;
mousey = MsgPtr->MouseY;
qual = MsgPtr->Qualifier;
if (class == IDCMP_MENUVERIFY && code == MENUHOT && mousey >= 0)
{ code = MENUCANCEL;
ReplyMsg(MsgPtr);
} else
{ GT_ReplyIMsg(MsgPtr); // seems that this doesn't work for menu verify messages
}
switch(class)
{
case IDCMP_CLOSEWINDOW:
cleanexit(EXIT_SUCCESS);
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(MainWindowPtr);
GT_EndRefresh(MainWindowPtr, TRUE);
break;
case IDCMP_MOUSEBUTTONS:
if ((code == MIDDLEDOWN || code == MENUUP) && !(qual & IEQUALIFIER_REPEAT))
{ if (mode == KEYBOARD)
{ return('0');
} elif (mode != ANYKEY || tickwait == -1)
{ return(-3);
} }
elif (code == SELECTDOWN && !(qual & IEQUALIFIER_REPEAT))
{ if (mode == KEYBOARD || (mode == ANYKEY && tickwait == -1))
{ if (mousey >= MESSAGEY)
{ return('0');
} else
{ return(-1);
} }
elif (mode == COUNTER)
{ if (mousey >= MESSAGEY)
{ return(-3);
}
counter = checkcounters(mousex, mousey, countertype);
if (counter == -1)
{ country = checkcountry(mousex, mousey);
*(countertype) = KINGDOM;
flash(country);
return(country);
} else
{ return(counter);
} }
elif (mode == COUNTRY)
{ if (mousey >= MESSAGEY)
{ return(-3);
}
counter = checkcounters(mousex, mousey, countertype);
if (counter == -1)
{ country = checkcountry(mousex, mousey);
*(countertype) = KINGDOM;
flash(country);
return(country);
} else
{ if (*(countertype) == HERO)
{ flash(hero[counter].where);
return(hero[counter].where);
} elif (*(countertype) == JARL)
{ flash(jarl[counter].where);
return(jarl[counter].where);
} elif (*(countertype) == MONSTER)
{ flash(monster[counter].where);
return(monster[counter].where);
} } } }
break;
case IDCMP_INTUITICKS:
if (mode == ANYKEY && tickwait != -1)
{ ticks++;
if (ticks >= tickwait)
{ return(-3);
} }
counter = checkcounters(mousex, mousey, countertype);
if (counter == -1)
{ country = checkcountry(mousex, mousey);
*(countertype) = KINGDOM;
showcountry(country);
} else
{ if (*(countertype) == HERO)
{ saywho(HERO, counter, FALSE, FALSE);
strcat(saystring, "(");
stcl_d(numberstring, hero[counter].strength);
strcat(saystring, numberstring);
strcat(saystring, "-");
stcl_d(numberstring, hero[counter].moves);
strcat(saystring, numberstring);
strcat(saystring, ")");
say(UPPER);
} elif (*(countertype) == JARL)
{ if (jarl[counter].face == FACEDOWN)
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_UNKNOWN_JARL, "Unknown jarl"));
strcat(saystring, " (?-?)");
} else
{ saywho(JARL, counter, FALSE, FALSE);
strcat(saystring, "(");
stcl_d(numberstring, jarl[counter].strength);
strcat(saystring, numberstring);
strcat(saystring, "-");
stcl_d(numberstring, jarl[counter].moves);
strcat(saystring, numberstring);
strcat(saystring, ")");
}
say(UPPER);
} elif (*(countertype) == MONSTER)
{ strcpy(saystring, monstertypes[monster[counter].species]);
strcat(saystring, " ");
strcat(saystring, monster[counter].name);
strcat(saystring, " (");
stcl_d(numberstring, monster[counter].strength);
strcat(saystring, numberstring);
strcat(saystring, "-");
stcl_d(numberstring, monster[counter].moves);
strcat(saystring, numberstring);
strcat(saystring, ")");
say(UPPER);
} elif (*(countertype) == TREASURE)
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_THE, "The"));
strcat(saystring, " ");
strcat(saystring, treasure[counter].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TREASURE2, "treasure"));
say(UPPER);
} elif (*(countertype) == SORD)
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
strcat(saystring, " ");
strcat(saystring, sord[counter].name);
say(UPPER);
} }
break;
case IDCMP_VANILLAKEY:
if (code == ' ' && (mode != ANYKEY || tickwait == -1))
{ return(-3);
} elif (code == 27) // Escape
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ cleanexit(EXIT_SUCCESS);
} elif (mode != ANYKEY || tickwait == -1)
{ return(-4);
} }
elif (mode == KEYBOARD || (mode == ANYKEY && tickwait == -1))
{ code = toupper(code);
return((SLONG) code);
}
elif (code == 8) // backspace
{ if (mode != ANYKEY || tickwait == -1)
{ return(-2);
} }
break;
case IDCMP_RAWKEY:
switch(code)
{
case HELP:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ summarywindow();
} else
{ counter = checkcounters(mousex, mousey, countertype);
if (counter == -1)
{ country = checkcountry(mousex, mousey);
if (country >= 0)
{ infowindow(KINGDOM, country);
} else
{ summarywindow();
} }
else
{ infowindow(*(countertype), counter);
} }
break;
default:
if
( (mode == KEYBOARD || (mode == ANYKEY && tickwait == -1))
&& code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER)
)
{ if (code == SCAN_F1 + cheat)
{ cheat++;
if (cheat == 5)
{ cheat = 0;
hero[BEOWULF].luck = 5000;
DisplayBeep(ScreenPtr);
} }
else cheat = 0;
}
break;
}
break;
case IDCMP_MENUPICK:
while (code != MENUNULL)
{ ItemPtr = ItemAddress(MenuPtr, code);
switch (MENUNUM(code))
{
case MN_PROJECT:
switch (ITEMNUM(code))
{
case IN_NEW:
return(-4);
case IN_SAVE:
savegame(FALSE);
break;
case IN_SAVEAS:
savegame(TRUE);
break;
case IN_QUIT:
cleanexit(EXIT_SUCCESS);
break;
default:
// IN_OPEN
break;
}
break;
case MN_HELP:
switch(ITEMNUM(code))
{
case IN_GAME_SUMMARY:
summarywindow();
break;
case IN_ABOUT:
helpabout();
break;
default:
break;
}
break;
default:
break;
}
code = ItemPtr->NextSelect;
}
break;
default:
break;
} } } }
MODULE void showcountry(SLONG country)
{ if (country >= 0 && country <= 65)
{ strcpy(saystring, world[country].name);
if (country <= 35)
{ strcat(saystring, " (");
stcl_d(numberstring, world[country].tax);
strcat(saystring, numberstring);
strcat(saystring, ")");
} }
else
{ strcpy(saystring, "-");
}
say(UPPER);
}
MODULE void phase1(void)
{ SLONG besthero = -1,
glory,
whichhero,
whichjarl,
whichmonster,
whichorder;
FLAG done;
/* "1. MOVEMENT. All heroes and jarls move. The hero with the most
glory and his or her jarls move first. In cases of ties the heroes
roll dice to see who goes first, with the highest roll going
first.
A counter may move as many areas as its movement factor. Each area
is defined by colour or, in the case of sea areas, by dividing
lines. Counters may move and remain in sea areas just as if they
were on land. There is no difference between land movement and sea
movement." */
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ hero[whichhero].moved =
hero[whichhero].hagall =
hero[whichhero].routed = FALSE;
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ jarl[whichjarl].hagall =
jarl[whichjarl].routed = FALSE;
}
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ monster[whichmonster].hagall = FALSE;
}
for (whichorder = 0; whichorder <= HEROES; whichorder++)
{ glory = -1;
done = TRUE;
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].alive && !hero[whichhero].moved)
{ done = FALSE;
if
( hero[whichhero].glory > glory
|| (hero[whichhero].glory == glory && !(rand() % 2))
)
{ besthero = whichhero;
glory = hero[whichhero].glory;
} } }
if (done)
{ order[whichorder] = -1;
} else
{ order[whichorder] = besthero;
hero[besthero].moved = TRUE;
} }
for (whichorder = 0; whichorder <= HEROES; whichorder++)
{ if (order[whichorder] == -1)
{ break;
} else
{ move(order[whichorder]);
} }
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ hero[whichhero].sea = NORMAL;
hero[whichhero].loseturn = FALSE;
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ jarl[whichjarl].sea = NORMAL;
jarl[whichjarl].loseturn = FALSE;
}
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ monster[whichmonster].sea = NORMAL;
} }
MODULE void phase2(void)
{ SLONG whichorder;
/* "2. COMBAT AND JARLS. Combat occurs in the same sequence as
movement; jarls are recruited after combat.
Heroes *must* attack at least one monster (if there is a monster)
in the area they are in during the combat portion of the turn. If
there is more than one monster they may choose which one they wish
to fight. They may attack more than one monster in an area." */
for (whichorder = 0; whichorder <= HEROES; whichorder++)
{ if (order[whichorder] == -1)
{ break;
} else
{ attack(order[whichorder]);
} } }
MODULE void attack(SLONG whichhero)
{ SLONG attackers,
countertype = -1,
country = -1,
totalstrength,
weakestmonster,
weakeststrength,
whichattack,
whichcountry,
whichjarl,
whichmonster,
whichmonster2,
whichrivalhero;
FLAG must = FALSE;
if (hero[whichhero].alive)
{ for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
{ hero[whichhero].attacked[whichattack] = -1;
hero[whichhero].attacktype[whichattack] = -1;
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
{ for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
{ jarl[whichjarl].attacked[whichattack] = -1;
jarl[whichjarl].attacktype[whichattack] = -1;
} } }
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ if (monster[whichmonster].alive && monster[whichmonster].where == hero[whichhero].where)
{ must = TRUE;
weakeststrength = 99;
for (whichmonster2 = 0; whichmonster2 <= MONSTERS; whichmonster2++)
{ if (monster[whichmonster2].alive && monster[whichmonster2].where == hero[whichhero].where && monster[whichmonster2].strength < weakeststrength)
{ weakeststrength = monster[whichmonster2].strength;
weakestmonster = whichmonster2;
} }
break;
} }
if (hero[whichhero].control == HUMAN)
{ while(1)
{ saywho(HERO, whichhero, TRUE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SELECT_ATTACKERS, "select attackers"));
strcat(saystring, "?");
say(LOWER);
country = getevent(COUNTRY, &countertype);
if (country >= 0)
{ if (hero[whichhero].alive && hero[whichhero].where == country && !hero[whichhero].routed)
{ attackers = 1;
select_hero(whichhero, FALSE);
hero[whichhero].attacking = TRUE;
} else
{ attackers = 0;
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].where == country && !jarl[whichjarl].routed && jarl[whichjarl].hero == whichhero)
{ attackers++;
select_jarl(whichjarl, FALSE);
jarl[whichjarl].attacking = TRUE;
} }
if (attackers)
{ refreshcounters();
getdefender(whichhero, country);
} }
elif (country == -3)
{ if (must && hero[whichhero].alive && !hero[whichhero].routed)
{ // check whether the hero has fought a monster
for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
{ if (hero[whichhero].attacktype[whichattack] == MONSTER)
{ return;
} }
saywho(HERO, whichhero, TRUE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_YOU_MUST_FIGHT_A_MONSTER, "you must fight a monster"));
strcat(saystring, ".");
say(LOWER);
anykey();
} else
{ if (hero[whichhero].attacking)
{ deselect_hero(whichhero, FALSE);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].attacking)
{ deselect_jarl(whichjarl, FALSE);
} }
refreshcounters();
return;
} } } }
elif (hero[whichhero].control == AMIGA)
{ for (whichcountry = 0; whichcountry <= 65; whichcountry++)
{ // check for possible enemies
if (!(totalstrength = getattackers(whichhero, whichcountry)))
{ continue;
}
for (whichrivalhero = 0; whichrivalhero <= HEROES; whichrivalhero++)
{ if (whichhero != whichrivalhero && hero[whichrivalhero].alive && hero[whichrivalhero].where == whichcountry && totalstrength > hero[whichhero].strength + 3)
{ amiga_attack(whichhero, HERO, whichrivalhero);
} }
if (!(totalstrength = getattackers(whichhero, whichcountry)))
{ continue;
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].hero != whichhero && jarl[whichjarl].where == whichcountry && (jarl[whichjarl].face == FACEDOWN || totalstrength > jarl[whichjarl].strength + 3))
{ amiga_attack(whichhero, JARL, whichjarl);
} }
if (!(totalstrength = getattackers(whichhero, whichcountry)))
{ continue;
}
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ if
( monster[whichmonster].alive
&& monster[whichmonster].where == whichcountry
&& ( (must && weakestmonster == whichmonster)
|| totalstrength > monster[whichmonster].strength + 1
) )
{ amiga_attack(whichhero, MONSTER, whichmonster);
} }
if (!(totalstrength = getattackers(whichhero, whichcountry)))
{ continue;
}
if (whichcountry <= 35 && world[whichcountry].hero != whichhero && !world[whichcountry].is && totalstrength > world[whichcountry].tax + 2)
{ amiga_attack(whichhero, KINGDOM, whichcountry);
} } } } }
MODULE void newgame(void)
{ SLONG whichhero, whichjarl, whichmonster, whichcountry, whichslot,
whichtreasure, whichsord;
OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW, NOSUB));
OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_OPEN, NOSUB));
OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE, NOSUB));
OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS, NOSUB));
OnMenu(MainWindowPtr, FULLMENUNUM(MN_HELP, IN_GAME_SUMMARY, NOSUB));
pathname[0] = 0;
/* 0. SET UP
"Divide the counters into four piles, keeping the heroes separate.
The four piles, all face down, should be: monsters of all sorts,
jarls, magic weapons [(swords)], and magic treasures.
Each player picks a hero counter to represent him or her in the game.
Players roll dice if two or more people want the same counter, and
high roll chooses first." */
reset_images();
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ hero[whichhero].strength = HERO_STRENGTH;
hero[whichhero].moves = HERO_MOVES;
hero[whichhero].name = trueheroname[whichhero];
hero[whichhero].attacking =
hero[whichhero].defending =
hero[whichhero].alive = FALSE;
hero[whichhero].verydead = TRUE;
hero[whichhero].glory =
hero[whichhero].luck =
hero[whichhero].wealth = 0;
hero[whichhero].rune = -1;
remove_hero(whichhero, FALSE);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ jarl[whichjarl].hero = -1;
jarl[whichjarl].wealth = 0;
jarl[whichjarl].attacking =
jarl[whichjarl].defending =
jarl[whichjarl].alive =
jarl[whichjarl].taken = FALSE;
remove_jarl(whichjarl, FALSE);
}
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ monster[whichmonster].alive = FALSE;
monster[whichmonster].taken = FALSE;
remove_monster(whichmonster, FALSE);
}
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ remove_treasure(whichtreasure, FALSE);
treasure[whichtreasure].taken = FALSE;
treasure[whichtreasure].possessor =
treasure[whichtreasure].possessortype =
treasure[whichtreasure].where = -1;
}
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ remove_sord(whichsord, FALSE);
sord[whichsord].taken = FALSE;
sord[whichsord].possessor =
sord[whichsord].possessortype =
sord[whichsord].where = -1;
}
for (whichcountry = 0; whichcountry <= 65; whichcountry++)
{ world[whichcountry].hero = -1;
world[whichcountry].is = FALSE;
for (whichslot = 0; whichslot <= SLOTS; whichslot++)
{ world[whichcountry].slot[whichslot] = FALSE;
} }
SetAPen(MainWindowPtr->RPort, BLACK);
RectFill(MainWindowPtr->RPort, 0, 0, SCREENXPIXEL, SCREENYPIXEL);
darken();
drawmap();
/* "Each player then picks a magic sword at random from the face-down
pile. Magic swords will not be given out again in the game and so all
of the left-over magic swords are put aside until the next game." */
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].control != NONE)
{ /* "Heroes begin the game in a randomly determined area (found in the
same manner as monsters are placed). This area should be noted on the
record sheet, as it is sometimes necessary to know a hero's home
country." */
newhero(whichhero, TRUE);
} }
place_monsters();
place_jarls();
refreshcounters();
turn = 1;
faxirides = 3;
}
MODULE void clearkybd(void)
{ struct IntuiMessage* MsgPtr;
while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
GT_ReplyIMsg(MsgPtr);
}
MODULE void titlescreen(void)
{ AUTO FLAG done;
AUTO SLONG whichhero;
AUTO struct IntuiMessage* MsgPtr;
AUTO ULONG class;
AUTO UWORD code, qual;
AUTO struct Gadget* addr;
AUTO struct MenuItem* ItemPtr;
loaded =
gameover = FALSE;
OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW, NOSUB));
OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_OPEN, NOSUB));
OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE, NOSUB));
OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS, NOSUB));
OffMenu(MainWindowPtr, FULLMENUNUM(MN_HELP, IN_GAME_SUMMARY, NOSUB));
SetAPen(MainWindowPtr->RPort, BLACK);
RectFill(MainWindowPtr->RPort, 0, 0, SCREENXPIXEL, SCREENYPIXEL);
drawlogo();
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ GT_SetGadgetAttrs(CycleGadgetPtr[whichhero], MainWindowPtr, NULL, GA_Disabled, FALSE, TAG_DONE);
}
GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GA_Disabled, FALSE, TAG_DONE);
RefreshGadgets(SpeedGadgetPtr, MainWindowPtr, NULL);
if (speed == 2)
{ GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GTSL_Level, 0, TAG_DONE); // kludgy
} else
{ GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GTSL_Level, 4 - speed, TAG_DONE); // kludgy
}
GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GTSL_Level, speed, TAG_DONE); // kludgy
SetAPen(MainWindowPtr->RPort, WHITE);
SetDrMd(MainWindowPtr->RPort, JAM1);
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ Move(MainWindowPtr->RPort, 212, 208 + (whichhero * 16) );
Text(MainWindowPtr->RPort, cycleheroname[whichhero], 10);
Move(MainWindowPtr->RPort, 212 + (cycleheropos[whichhero] * 8), 208 + (whichhero * 16) + 1);
Text(MainWindowPtr->RPort, "_", 1);
}
if (cliload)
{ if (loadgame(FALSE))
{ loaded = TRUE;
} else
{ cliload = FALSE;
} }
if (!cliload)
{ done = FALSE;
do
{ while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
{ addr = (struct Gadget *) MsgPtr->IAddress;
class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
GT_ReplyIMsg(MsgPtr);
switch (class)
{
case IDCMP_RAWKEY:
if (!(qual & IEQUALIFIER_REPEAT))
{ switch (code)
{
case SCAN_F1:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[0].control == 0)
{ hero[0].control = 2;
} else
{ hero[0].control--;
} }
else
{ if (hero[0].control == 2)
{ hero[0].control = 0;
} else
{ hero[0].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[0], MainWindowPtr, NULL, GTCY_Active, hero[0].control, TAG_DONE);
break;
case SCAN_F2:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[1].control == 0)
{ hero[1].control = 2;
} else
{ hero[1].control--;
} }
else
{ if (hero[1].control == 2)
{ hero[1].control = 0;
} else
{ hero[1].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[1], MainWindowPtr, NULL, GTCY_Active, hero[1].control, TAG_DONE);
break;
case SCAN_F3:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[2].control == 0)
{ hero[2].control = 2;
} else
{ hero[2].control--;
} }
else
{ if (hero[2].control == 2)
{ hero[2].control = 0;
} else
{ hero[2].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, hero[2].control, TAG_DONE);
break;
case SCAN_F4:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[3].control == 0)
{ hero[3].control = 2;
} else
{ hero[3].control--;
} }
else
{ if (hero[3].control == 2)
{ hero[3].control = 0;
} else
{ hero[3].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[3], MainWindowPtr, NULL, GTCY_Active, hero[3].control, TAG_DONE);
break;
case SCAN_F5:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[4].control == 0)
{ hero[4].control = 2;
} else
{ hero[4].control--;
} }
else
{ if (hero[4].control == 2)
{ hero[4].control = 0;
} else
{ hero[4].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[4], MainWindowPtr, NULL, GTCY_Active, hero[4].control, TAG_DONE);
break;
case SCAN_F6:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[5].control == 0)
{ hero[5].control = 2;
} else
{ hero[5].control--;
} }
else
{ if (hero[5].control == 2)
{ hero[5].control = 0;
} else
{ hero[5].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[5], MainWindowPtr, NULL, GTCY_Active, hero[5].control, TAG_DONE);
break;
case HELP:
helpabout();
break;
default:
break;
} }
break;
case IDCMP_VANILLAKEY:
code = toupper(code);
switch(code)
{
case ' ':
case 13: // Return or Enter
done = TRUE;
break;
case 27: // Escape
cleanexit(EXIT_SUCCESS);
break;
case '1':
case 'B':
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[0].control == 0)
{ hero[0].control = 2;
} else
{ hero[0].control--;
} }
else
{ if (hero[0].control == 2)
{ hero[0].control = 0;
} else
{ hero[0].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[0], MainWindowPtr, NULL, GTCY_Active, hero[0].control, TAG_DONE);
break;
case '!':
if (hero[0].control == 0)
{ hero[0].control = 2;
} else
{ hero[0].control--;
}
GT_SetGadgetAttrs(CycleGadgetPtr[0], MainWindowPtr, NULL, GTCY_Active, hero[0].control, TAG_DONE);
break;
case '2':
case 'U':
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[1].control == 0)
{ hero[1].control = 2;
} else
{ hero[1].control--;
} }
else
{ if (hero[1].control == 2)
{ hero[1].control = 0;
} else
{ hero[1].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[1], MainWindowPtr, NULL, GTCY_Active, hero[1].control, TAG_DONE);
break;
case '@':
if (hero[1].control == 0)
{ hero[1].control = 2;
} else
{ hero[1].control--;
}
GT_SetGadgetAttrs(CycleGadgetPtr[1], MainWindowPtr, NULL, GTCY_Active, hero[1].control, TAG_DONE);
break;
case '3':
case 'E':
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[2].control == 0)
{ hero[2].control = 2;
} else
{ hero[2].control--;
} }
else
{ if (hero[2].control == 2)
{ hero[2].control = 0;
} else
{ hero[2].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, hero[2].control, TAG_DONE);
break;
case '#':
if (hero[2].control == 0)
{ hero[2].control = 2;
} else
{ hero[2].control--;
}
GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, hero[2].control, TAG_DONE);
break;
case '4':
case 'R':
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[3].control == 0)
{ hero[3].control = 2;
} else
{ hero[3].control--;
} }
else
{ if (hero[3].control == 2)
{ hero[3].control = 0;
} else
{ hero[3].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[3], MainWindowPtr, NULL, GTCY_Active, hero[3].control, TAG_DONE);
break;
case '$':
if (hero[3].control == 0)
{ hero[3].control = 2;
} else
{ hero[3].control--;
}
GT_SetGadgetAttrs(CycleGadgetPtr[3], MainWindowPtr, NULL, GTCY_Active, hero[3].control, TAG_DONE);
break;
case '5':
case 'S':
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[4].control == 0)
{ hero[4].control = 2;
} else
{ hero[4].control--;
} }
else
{ if (hero[4].control == 2)
{ hero[4].control = 0;
} else
{ hero[4].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[4], MainWindowPtr, NULL, GTCY_Active, hero[4].control, TAG_DONE);
break;
case '%':
if (hero[4].control == 0)
{ hero[4].control = 2;
} else
{ hero[4].control--;
}
GT_SetGadgetAttrs(CycleGadgetPtr[4], MainWindowPtr, NULL, GTCY_Active, hero[4].control, TAG_DONE);
break;
case '6':
case 'T':
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (hero[5].control == 0)
{ hero[5].control = 2;
} else
{ hero[5].control--;
} }
else
{ if (hero[5].control == 2)
{ hero[5].control = 0;
} else
{ hero[5].control++;
} }
GT_SetGadgetAttrs(CycleGadgetPtr[5], MainWindowPtr, NULL, GTCY_Active, hero[5].control, TAG_DONE);
break;
case '^':
if (hero[5].control == 0)
{ hero[5].control = 2;
} else
{ hero[5].control--;
}
GT_SetGadgetAttrs(CycleGadgetPtr[5], MainWindowPtr, NULL, GTCY_Active, hero[5].control, TAG_DONE);
break;
default:
break;
}
break;
case IDCMP_MENUPICK:
while (code != MENUNULL)
{ ItemPtr = ItemAddress(MenuPtr, code);
switch (MENUNUM(code))
{
case MN_PROJECT:
switch (ITEMNUM(code))
{
case IN_NEW:
done = TRUE;
break;
case IN_OPEN:
if (loadgame(TRUE))
{ done = TRUE;
loaded = TRUE;
}
break;
case IN_QUIT:
cleanexit(EXIT_SUCCESS);
break;
default:
// IN_SAVE, IN_SAVEAS
break;
}
break;
case MN_HELP:
switch(ITEMNUM(code))
{
case IN_ABOUT:
helpabout();
break;
default:
break;
}
break;
default:
break;
}
code = ItemPtr->NextSelect;
}
break;
case IDCMP_MOUSEBUTTONS:
if (code == SELECTDOWN && !(qual & IEQUALIFIER_REPEAT))
{ done = TRUE;
}
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(MainWindowPtr);
GT_EndRefresh(MainWindowPtr, TRUE);
break;
case IDCMP_GADGETUP:
if (addr == SpeedGadgetPtr)
{ speed = code;
} else
{ for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (addr == CycleGadgetPtr[whichhero])
{ hero[whichhero].control = code;
break;
} } }
break;
case IDCMP_CLOSEWINDOW:
cleanexit(EXIT_SUCCESS);
break;
default:
; /* IDCMP_INTUITICKS */
break;
} }
if (done)
{ done = FALSE;
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].control != NONE)
{ done = TRUE;
break;
} }
if (!done)
{ ; // DisplayBeep(ScreenPtr); // no heroes active
} }
} while (!done);
}
cliload = FALSE;
if (!loaded)
{ for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ GT_SetGadgetAttrs(CycleGadgetPtr[whichhero], MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
}
GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
}
if (speed == 4)
{ tickwait = -1;
} else
{ tickwait = speed * 8;
} }
MODULE void gain(SLONG whichhero, SLONG glory, SLONG luck)
{ SLONG result;
if (glory == 0 && luck == 0)
{ return;
}
if (hero[whichhero].control == HUMAN)
{ saywho(HERO, whichhero, TRUE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GAIN, "gain"));
strcat(saystring, " ");
stcl_d(numberstring, glory);
strcat(saystring, numberstring);
strcat(saystring, " (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_GLORY, "G"));
strcat(saystring, ")");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_GLORY, "lory"));
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OR, "or"));
strcat(saystring, " ");
stcl_d(numberstring, luck);
strcat(saystring, numberstring);
strcat(saystring, " (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_LUCK, "L"));
strcat(saystring, ")");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_LUCK, "uck"));
strcat(saystring, "?");
say(LOWER);
do
{ result = getevent(KEYBOARD, NULL);
} while (result != onekey[ONEKEY_GLORY] && result != onekey[ONEKEY_LUCK]);
if (result == onekey[ONEKEY_GLORY])
{ hero[whichhero].glory += glory;
} else
{ // assert(result == onekey[ONEKEY_LUCK]);
hero[whichhero].luck += luck;
} }
else
{ hero[whichhero].luck += luck;
} }
MODULE void move(SLONG whichhero)
{ SLONG country,
decision,
freemove,
i,
movearray[66],
moves,
oldcountry,
stop,
whichconnection,
whichjarl,
whichmove = -1,
whichrealmove,
whichtreasure,
whichsord;
FLAG legal;
// HEROES
if (hero[whichhero].alive)
{ select_hero(whichhero, TRUE);
moves = getmoves(HERO, whichhero, FALSE);
if (hero[whichhero].control == HUMAN)
{ if
( treasure[FREYFAXI].possessortype == HERO
&& treasure[FREYFAXI].possessor == whichhero
)
{ // assert(treasure[FREYFAXI].where == -1);
// assert(faxirides >= 1);
if (ask_faxi(HERO, whichhero))
{ moves = getmoves(HERO, whichhero, TRUE);
} }
movearray[0] = hero[whichhero].where;
whichrealmove = 1;
if (moves >= 1)
{ oldcountry = hero[whichhero].where;
whichmove =
whichrealmove = 1;
freemove = FALSE;
do
{ saywho(HERO, whichhero, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
strcat(saystring, " ");
strcat(saystring, world[hero[whichhero].where].name);
strcat(saystring, ", ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_MOVE, "move"));
strcat(saystring, " ");
stcl_d(numberstring, whichmove);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
strcat(saystring, " ");
stcl_d(numberstring, moves);
strcat(saystring, numberstring);
strcat(saystring, "?");
say(LOWER);
do
{ country = getevent(COUNTRY, NULL);
} while ((country < -3 || country > 65) || country == -1);
if (country == -3)
{ break;
} elif (country == -2)
{ whichmove =
whichrealmove = 1;
unslot_hero(whichhero);
hero[whichhero].where = oldcountry;
move_hero(whichhero, TRUE);
freemove = FALSE;
} else
{ legal = FALSE;
for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
{ if (world[hero[whichhero].where].connection[whichconnection] == country)
{ legal = TRUE;
break; // for speed
} }
if (legal)
{ if
( hero[whichhero].sea == BAD
&& ( world[country].type == SEA
|| world[country].type == ISLE
) )
{ legal = FALSE;
saywho(HERO, whichhero, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
strcat(saystring, ".");
say(LOWER);
anykey();
} }
if (legal)
{ unslot_hero(whichhero);
hero[whichhero].where = country;
move_hero(whichhero, TRUE);
if (whichrealmove <= 65)
{ movearray[whichrealmove++] = country;
}
if (hero[whichhero].sea == GOOD)
{ if (!freemove)
{ if
( world[hero[whichhero].where].type == SEA
|| world[hero[whichhero].where].type == ISLE
)
{ freemove = TRUE;
}
whichmove++;
} else
{ if
( world[hero[whichhero].where].type == LAND
)
{ freemove = FALSE;
whichmove++;
} } }
else
{ whichmove++;
} }
else
{ ; // DisplayBeep(ScreenPtr);
} }
} while (whichmove <= moves);
}
/* We ask instead of automatically taking because theoretically a hero
might want to pass on the opportunity, so he can allow one of his jarls
in the same square to take the treasure. */
for (i = 0; i < whichrealmove; i++)
{ for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (movearray[i] == jarl[whichjarl].where && jarl[whichjarl].hero == whichhero)
{ // hero moved past jarl during move
hero[whichhero].wealth += jarl[whichjarl].wealth;
jarl[whichjarl].wealth = 0;
} } }
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == hero[whichhero].where)
{ // assert(treasure[whichtreasure].possessor = -1);
asktreasure(HERO, whichhero, whichtreasure);
} }
if (needsord(HERO, whichhero))
{ for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == hero[whichhero].where)
{ // assert(sord[whichsord].possessor = -1);
if (asksord(HERO, whichhero, whichsord))
{ break;
} } } }
if
( treasure[BROSUNGNECKLACE].possessortype == HERO
&& treasure[BROSUNGNECKLACE].possessor == whichhero
)
{ brosung(HERO, whichhero);
} }
else
{ // assert(hero[whichhero].control == AMIGA);
movearray[0] = hero[whichhero].where;
whichrealmove = 1;
if (moves >= 1)
{ saywho(HERO, whichhero, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_MOVING, "is moving"));
strcat(saystring, "...");
say(LOWER);
freemove = FALSE;
if
( hero[whichhero].wounded
&& ( hero[whichhero].rune == ING
|| hero[whichhero].where == hero[whichhero].homewhere
) )
{ stop = TRUE;
} else
{ stop = assess(HERO, hero[whichhero].where);
}
for (whichmove = 1; whichmove <= moves; whichmove++)
{ if (!stop)
{ stop = assess(HERO, whichhero);
}
if (stop)
{ break;
}
do
{ decision = rand() % (CONNECTIONS + 1);
} while (world[hero[whichhero].where].connection[decision] == -1);
if
( hero[whichhero].sea == BAD
&& ( world[world[hero[whichhero].where].connection[decision]].type == SEA
|| world[world[hero[whichhero].where].connection[decision]].type == ISLE
) )
{ whichmove--;
} else
{ unslot_hero(whichhero);
hero[whichhero].where = world[hero[whichhero].where].connection[decision];
move_hero(whichhero, TRUE);
if (whichrealmove <= 65)
{ movearray[whichrealmove++] = hero[whichhero].where;
}
if (hero[whichhero].sea == GOOD)
{ if (!freemove)
{ if
( world[hero[whichhero].where].type == SEA
|| world[hero[whichhero].where].type == ISLE
)
{ freemove = TRUE;
} }
else
{ if
( world[hero[whichhero].where].type == LAND
)
{ freemove = FALSE;
} else
{ whichmove--;
} } } } } }
for (i = 0; i < whichrealmove; i++)
{ for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (movearray[i] == jarl[whichjarl].where && jarl[whichjarl].hero == whichhero)
{ // hero moved past jarl during move
hero[whichhero].wealth += jarl[whichjarl].wealth;
jarl[whichjarl].wealth = 0;
} } }
// Amiga always takes whatever it can.
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == hero[whichhero].where)
{ // assert(treasure[whichtreasure].possessor = -1);
remove_treasure(whichtreasure, TRUE);
treasure[whichtreasure].possessortype = HERO;
treasure[whichtreasure].possessor = whichhero;
treasure[whichtreasure].where = -1;
saywho(HERO, whichhero, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_THE, "takes the"));
strcat(saystring, " ");
strcat(saystring, treasure[whichtreasure].name);
strcat(saystring, ".");
say(LOWER);
anykey();
} }
if (needsord(HERO, whichhero))
{ for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == hero[whichhero].where)
{ // assert(sord[whichsord].possessor = -1);
remove_sord(whichsord, TRUE);
sord[whichsord].possessortype = HERO;
sord[whichsord].possessor = whichhero;
sord[whichsord].where = -1;
saywho(HERO, whichhero, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_SWORD, "takes sword"));
strcat(saystring, " ");
strcat(saystring, sord[whichsord].name);
strcat(saystring, ".");
say(LOWER);
anykey();
break;
} } } }
// check healing
if
( whichmove == 1
&& hero[whichhero].wounded
&& ( hero[whichhero].where == hero[whichhero].homewhere
|| hero[whichhero].rune == ING
) )
{ hero[whichhero].wounded = FALSE;
saywho(HERO, whichhero, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HEALS, "heals"));
strcat(saystring, ".");
say(LOWER);
anykey();
}
deselect_hero(whichhero, TRUE);
// JARLS
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
{ select_jarl(whichjarl, TRUE);
moves = getmoves(JARL, whichjarl, FALSE);
if (hero[whichhero].control == HUMAN)
{ if
( treasure[FREYFAXI].possessortype == JARL
&& treasure[FREYFAXI].possessor == whichjarl
)
{ // assert(treasure[FREYFAXI].where == -1);
// assert(faxirides >= 1);
if (ask_faxi(JARL, whichjarl))
{ moves = getmoves(JARL, whichjarl, TRUE);
} }
movearray[0] = jarl[whichjarl].where;
whichmove = 1;
if (moves >= 1)
{ oldcountry = jarl[whichjarl].where;
do
{ saywho(JARL, whichjarl, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
strcat(saystring, " ");
strcat(saystring, world[jarl[whichjarl].where].name);
strcat(saystring, ", ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_MOVE, "move"));
strcat(saystring, " ");
stcl_d(numberstring, whichmove);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
strcat(saystring, " ");
stcl_d(numberstring, moves);
strcat(saystring, numberstring);
strcat(saystring, "?");
say(LOWER);
do
{ country = getevent(COUNTRY, NULL);
} while ((country < -3 || country > 65) || country == -1);
if (country == -3)
{ break;
} elif (country == -2)
{ whichmove = 1;
unslot_jarl(whichjarl);
jarl[whichjarl].where = oldcountry;
move_jarl(whichjarl, TRUE);
} else
{ legal = FALSE;
for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
{ if (world[jarl[whichjarl].where].connection[whichconnection] == country)
{ legal = TRUE;
break; // for speed
} }
if (legal)
{ if
( jarl[whichjarl].sea == BAD
&& ( world[country].type == SEA
|| world[country].type == ISLE
) )
{ legal = FALSE;
saywho(JARL, whichjarl, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
strcat(saystring, ".");
say(LOWER);
anykey();
} }
if (legal)
{ unslot_jarl(whichjarl);
jarl[whichjarl].where = country;
move_jarl(whichjarl, TRUE);
movearray[whichmove] = country;
whichmove++;
} else
{ ; // DisplayBeep(ScreenPtr);
} }
} while (whichmove <= moves);
}
for (i = 0; i < whichmove; i++)
{ if (movearray[i] == hero[whichhero].where)
{ // jarl moved past hero during move
hero[whichhero].wealth += jarl[whichjarl].wealth;
jarl[whichjarl].wealth = 0;
} }
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == jarl[whichjarl].where)
{ // assert(treasure[whichtreasure].possessor = -1);
asktreasure(JARL, whichjarl, whichtreasure);
} }
if (needsord(JARL, whichjarl))
{ for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == jarl[whichjarl].where)
{ // assert(sord[whichsord].possessor = -1);
if (asksord(JARL, whichjarl, whichsord))
{ break;
} } } }
if
( treasure[BROSUNGNECKLACE].possessortype == JARL
&& treasure[BROSUNGNECKLACE].possessor == whichjarl
)
{ brosung(JARL, whichjarl);
} }
elif (hero[whichhero].control == AMIGA)
{ saywho(JARL, whichjarl, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_MOVING, "is moving"));
strcat(saystring, "...");
say(LOWER);
movearray[0] = jarl[whichjarl].where;
whichmove = 1;
if (moves >= 1)
{ for (whichmove = 1; whichmove <= moves; whichmove++)
{ stop = assess(JARL, whichjarl);
if (stop)
{ break;
}
do
{ decision = rand() % (CONNECTIONS + 1);
} while (world[jarl[whichjarl].where].connection[decision] == -1);
if
( jarl[whichjarl].sea == BAD
&& ( world[world[jarl[whichjarl].where].connection[decision]].type == SEA
|| world[world[jarl[whichjarl].where].connection[decision]].type == ISLE
) )
{ whichmove--;
} else
{ unslot_jarl(whichjarl);
jarl[whichjarl].where = world[jarl[whichjarl].where].connection[decision];
move_jarl(whichjarl, TRUE);
movearray[whichmove] = jarl[whichjarl].where;
} } }
for (i = 0; i < whichmove; i++)
{ if (movearray[i] == hero[whichhero].where)
{ // jarl moved past hero during move
hero[whichhero].wealth += jarl[whichjarl].wealth;
jarl[whichjarl].wealth = 0;
} }
// Amiga always takes whatever it can.
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == jarl[whichjarl].where)
{ // assert(treasure[whichtreasure].possessor = -1);
remove_treasure(whichtreasure, TRUE);
treasure[whichtreasure].possessortype = JARL;
treasure[whichtreasure].possessor = whichjarl;
treasure[whichtreasure].where = -1;
saywho(JARL, whichjarl, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_THE, "takes the"));
strcat(saystring, " ");
strcat(saystring, treasure[whichtreasure].name);
strcat(saystring, ".");
say(LOWER);
anykey();
} }
if (needsord(JARL, whichjarl))
{ for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == jarl[whichjarl].where)
{ // assert(sord[whichsord].possessor = -1);
remove_sord(whichsord, TRUE);
sord[whichsord].possessortype = HERO;
sord[whichsord].possessor = whichhero;
sord[whichsord].where = -1;
saywho(JARL, whichjarl, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_SWORD, "takes sword"));
strcat(saystring, " ");
strcat(saystring, sord[whichsord].name);
strcat(saystring, ".");
say(LOWER);
anykey();
break;
} } } }
deselect_jarl(whichjarl, TRUE);
} } } }
MODULE void helpabout(void)
{ SBYTE line;
FLAG done = FALSE;
ULONG class;
UWORD code, qual;
struct IntuiMessage* MsgPtr;
if (!(HelpWindowPtr = (struct Window *) OpenWindowTags(NULL,
WA_Left, (SCREENXPIXEL / 2) - (ABOUTXPIXEL / 2),
WA_Top, (SCREENYPIXEL / 2) - (ABOUTYPIXEL / 2),
WA_Width, ABOUTXPIXEL,
WA_Height, ABOUTYPIXEL,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
WA_Title, abouttitle,
WA_Gadgets, NULL,
WA_CustomScreen, ScreenPtr,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_NoCareRefresh, TRUE,
WA_Activate, TRUE,
TAG_DONE))
)
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open About... window!\0", 24);
cleanexit(EXIT_FAILURE);
} else
{ SetAPen(HelpWindowPtr->RPort, LIGHTGREY);
RectFill(HelpWindowPtr->RPort, 8, 13, ABOUTXPIXEL - 10, ABOUTYPIXEL - 6);
SetAPen(HelpWindowPtr->RPort, BLACK);
SetDrMd(HelpWindowPtr->RPort, JAM1);
for (line = 0; line <= ABOUTLINES; line++)
{ Move(HelpWindowPtr->RPort, about[line].x, about[line].y);
Text(HelpWindowPtr->RPort, about[line].text, (SBYTE) strlen(about[line].text));
}
DrawBevelBox(HelpWindowPtr->RPort, 16, 20, 44 + 4, 38 + 4, GT_VisualInfo, VisualInfoPtr, GTBB_Recessed, TRUE, TAG_END);
drawabout();
while(!done)
{ Wait(1L << HelpWindowPtr->UserPort->mp_SigBit);
while (MsgPtr = (struct IntuiMessage *) GetMsg(HelpWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
ReplyMsg((struct Message *) MsgPtr);
switch(class)
{
case IDCMP_CLOSEWINDOW:
done = TRUE;
break;
case IDCMP_RAWKEY:
if (!(qual & IEQUALIFIER_REPEAT) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
{ done = TRUE;
}
break;
default:
break;
} } }
CloseWindow(HelpWindowPtr);
HelpWindowPtr = NULL;
clearkybd();
} }
MODULE void resettime(void)
{ struct timerequest* TimerIORequestPtr;
struct timeval timeval;
if (!(TimerIORequestPtr = (struct timerequest *) AllocVec(sizeof(struct timerequest), MEMF_PUBLIC | MEMF_CLEAR)))
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Out of memory!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *) TimerIORequestPtr, 0))
{ FreeVec(TimerIORequestPtr);
DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open timer.device!\0", 24);
cleanexit(EXIT_FAILURE);
}
TimerBase = (struct Library *) TimerIORequestPtr->tr_node.io_Device;
GetSysTime(&timeval);
srand((UWORD) timeval.tv_micro);
// no need to abort timer I/O requests, as we never send any
CloseDevice((struct IORequest *) TimerIORequestPtr);
FreeVec(TimerIORequestPtr);
}
MODULE void anykey(void)
{ if (tickwait != 0)
{ getevent(ANYKEY, NULL);
} }
MODULE void waitkey(void)
{ SLONG realtickwait = tickwait;
tickwait = -1;
getevent(ANYKEY, NULL);
tickwait = realtickwait;
}
MODULE SLONG getluck(SLONG whichhero)
{ SLONG result;
while(1)
{ do
{ result = getevent(KEYBOARD, NULL);
} while (result < '0' || result > '9');
if (result == '0')
{ return(0);
} else
{ result -= '0';
}
if (result > hero[whichhero].luck)
{ ; // DisplayBeep(ScreenPtr);
} else
{ hero[whichhero].luck -= result;
return(result);
} } }
MODULE void phase3(void)
{ FLAG ok;
SBYTE whichhero, whichcountry, whichjarl;
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].control != NONE && !(hero[whichhero].verydead))
/* Note that we even do this for dead heroes: they can keep their
kingdoms (for now) where they have jarls, as they may be
promoting a jarl, in which case they are allowed to keep their
kingdoms. */
{ for (whichcountry = 0; whichcountry <= 35; whichcountry++)
{ if (world[whichcountry].hero == whichhero)
{ // determine whether the hero or one of his jarls is there
ok = FALSE;
if (!world[whichcountry].is)
{ if (hero[whichhero].where == whichcountry)
{ ok = TRUE;
hero[whichhero].wealth += world[whichcountry].tax;
if (hero[whichhero].rune == GEOFU)
{ hero[whichhero].wealth++;
} }
else
{ for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if
( jarl[whichjarl].alive
&& jarl[whichjarl].hero == whichhero
&& jarl[whichjarl].where == whichcountry
) // taxes are given to the first friendly jarl found
{ ok = TRUE;
jarl[whichjarl].wealth += world[whichcountry].tax;
if (hero[whichhero].rune == GEOFU)
{ jarl[whichjarl].wealth++;
}
break;
} } } }
if (!ok)
{ world[whichcountry].hero = -1;
darken();
strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_KINGDOM, "'s kingdom"));
strcat(saystring, " ");
strcat(saystring, world[whichcountry].name);
strcat(saystring, " (");
stcl_d(numberstring, world[whichcountry].tax);
strcat(saystring, numberstring);
strcat(saystring, ") ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_BEEN_OVERRUN, "has been overrun"));
strcat(saystring, ".");
say(LOWER);
anykey();
} } } } } }
MODULE void gods(SLONG whichhero)
{ SLONG whichgod, whichprayer, decision;
FLAG heard;
whichgod = rand() % 6;
whichprayer = d6();
switch(whichgod)
{
case FREY:
strcpy(saystring, "Frey ");
heard = FALSE;
if (whichprayer <= 4)
{ // assert(whichprayer >= 1);
hero[whichhero].maidens++;
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_W_S_A_M_T_H_H, "will send a maiden to heal hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_NEXT_WOUND, "'s next wound"));
strcat(saystring, ".");
} else
{ // assert(whichprayer == 5 || whichprayer == 6);
hero[whichhero].maidens += 2;
strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_W_S_A_M_T_H_H, "will send a maiden to heal hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_NEXT_TWO_WOUNDS, "'s next two wounds"));
strcat(saystring, ".");
}
break;
case LOKI:
strcpy(saystring, "Loki ");
heard = FALSE;
if (whichprayer <= 3)
{ // assert(whichprayer >= 0);
hero[whichhero].luck--;
if (hero[whichhero].luck < 0)
{ hero[whichhero].luck = 0;
}
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_A_P_O_L_F_H, "steals a point of luck from hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, ".");
} else
{ // assert(whichprayer >= 4 && whichprayer <= 6);
hero[whichhero].luck++;
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GRANTS_HERO, "grants hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_A_P_O_L_F_H_D, "a point of luck for his daring"));
strcat(saystring, ".");
}
break;
case NJORD:
strcpy(saystring, "Njord ");
heard = FALSE;
if (whichprayer == 1 || whichprayer == 2)
{ hero[whichhero].sea = GOOD;
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TO_MOVE_BY_SEA_NEXT_TURN, "to move by sea next turn"));
strcat(saystring, ".");
} elif (whichprayer == 3 || whichprayer == 4)
{ decision = d6();
hero[whichhero].wealth += decision;
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GIVES, "gives"));
strcat(saystring, " ");
stcl_d(numberstring, decision);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS_TO_HERO, "golden marks to hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AS_A_GIFT, "as a gift"));
strcat(saystring, ".");
} elif (whichprayer == 5)
{ decision = d6();
if (decision > hero[whichhero].wealth)
{ decision = hero[whichhero].wealth;
}
hero[whichhero].wealth -= decision;
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"));
strcat(saystring, " ");
stcl_d(numberstring, decision);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS_FROM_HERO, "golden marks from hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AS_DUE_TRIBUTE, "as due tribute"));
strcat(saystring, ".");
} else
{ // assert(whichprayer == 6);
hero[whichhero].sea = BAD;
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_PREVENTS_HERO, "prevents hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_F_T_B_S_N_T, "from travelling by sea next turn"));
strcat(saystring, ".");
}
break;
case ODIN:
hero[whichhero].god = ODIN;
heard = TRUE;
strcpy(saystring, "Odin ");
break;
case THOR:
hero[whichhero].god = THOR;
heard = TRUE;
strcpy(saystring, "Thor ");
break;
case TYR:
hero[whichhero].god = TYR;
heard = TRUE;
strcpy(saystring, "Tyr ");
break;
default:
break;
}
if (heard)
{ strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HEARD_THE_PRAYER_OF_HERO, "heard the prayer of hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, ".");
}
say(LOWER);
anykey();
}
MODULE FLAG loadgame(FLAG aslwindow)
{ SLONG offset = 12, whichhero, whichjarl, whichmonster, whichcountry,
whichslot, whichtreasure, whichsord;
TEXT newpathname[255];
BPTR FileHandle /* = NULL */ ;
FLAG ok;
if (aslwindow)
{ if
( AslRequestTags
( ASLRqPtr,
ASL_Hail, GetCatalogStr(li.li_Catalog, MSG_LOAD_GAME, "Load Game"),
ASL_FuncFlags, FILF_PATGAD,
TAG_DONE
)
&& *(ASLRqPtr->rf_File)
)
{ strcpy(newpathname, ASLRqPtr->rf_Dir);
AddPart(newpathname, ASLRqPtr->rf_File, 254);
ok = TRUE;
} else
{ ok = FALSE;
} }
else
{ ok = TRUE;
strcpy(newpathname, pathname);
}
// 'SAGA 1.0' fieldsets are 544 bytes long, plus the version string.
if (ok)
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_LOADING, "Loading"));
strcat(saystring, " ");
strcat(saystring, newpathname);
strcat(saystring, "...");
say(LOWER);
if (!(FileHandle = Open(newpathname, MODE_OLDFILE)))
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_OPEN, "Can't open"));
strcat(saystring, " ");
strcat(saystring, newpathname);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FOR_READING, "for reading"));
strcat(saystring, "!");
say(LOWER);
return(FALSE);
}
// read file
if (Read(FileHandle, IOBuffer, 544) != 544)
{ Close(FileHandle);
// FileHandle = NULL;
strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_READ_FROM, "Can't read from"));
strcat(saystring, " ");
strcat(saystring, newpathname);
strcat(saystring, "!");
say(LOWER);
return(FALSE);
}
if (strcmp(IOBuffer, "SAGA 1.0 "))
{ Close(FileHandle);
// FileHandle = NULL;
strcpy(saystring, newpathname);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_I_N_A_V_S_G_F, "is not a valid saved game file"));
strcat(saystring, "!");
say(LOWER);
return(FALSE);
}
turn = (SLONG) ((SBYTE) IOBuffer[10]);
faxirides = (SLONG) ((SBYTE) IOBuffer[11]);
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ hero[whichhero].control = (SLONG) ((SBYTE) IOBuffer[offset++] );
hero[whichhero].alive = (FLAG) ((SBYTE) IOBuffer[offset++] );
hero[whichhero].verydead = (FLAG) ((SBYTE) IOBuffer[offset++] );
hero[whichhero].moves = (SLONG) ((SBYTE) IOBuffer[offset++] );
hero[whichhero].god = (SLONG) ((SBYTE) IOBuffer[offset++] );
hero[whichhero].rune = (SLONG) ((SBYTE) IOBuffer[offset++] );
hero[whichhero].where = (SLONG) ((SBYTE) IOBuffer[offset++] );
hero[whichhero].homewhere = (SLONG) ((SBYTE) IOBuffer[offset++] );
hero[whichhero].promoted = (SLONG) ((SBYTE) IOBuffer[offset++] );
hero[whichhero].wounded = (FLAG) ((SBYTE) IOBuffer[offset++] );
hero[whichhero].wealth = (SLONG) ((IOBuffer[offset++] * 256) + IOBuffer[offset++]);
hero[whichhero].glory = (SLONG) ((IOBuffer[offset++] * 256) + IOBuffer[offset++]);
hero[whichhero].luck = (SLONG) ((IOBuffer[offset++] * 256) + IOBuffer[offset++]);
hero[whichhero].sea = (SLONG) ((SBYTE) IOBuffer[offset++]);
hero[whichhero].loseturn = (FLAG) ((SBYTE) IOBuffer[offset++]);
hero[whichhero].maidens = (SLONG) ((SBYTE) IOBuffer[offset++]);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ jarl[whichjarl].where = (SLONG) ((SBYTE) IOBuffer[offset++]);
jarl[whichjarl].homewhere = (SLONG) ((SBYTE) IOBuffer[offset++]);
jarl[whichjarl].face = (SLONG) ((SBYTE) IOBuffer[offset++]);
jarl[whichjarl].hero = (SLONG) ((SBYTE) IOBuffer[offset++]);
jarl[whichjarl].taken = (FLAG) ((SBYTE) IOBuffer[offset++]);
jarl[whichjarl].sea = (SLONG) ((SBYTE) IOBuffer[offset++]);
jarl[whichjarl].loseturn = (FLAG) ((SBYTE) IOBuffer[offset++]);
jarl[whichjarl].alive = (FLAG) ((SBYTE) IOBuffer[offset++]);
}
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ monster[whichmonster].taken = (FLAG) ((SBYTE) IOBuffer[offset++]);
monster[whichmonster].alive = (FLAG) ((SBYTE) IOBuffer[offset++]);
monster[whichmonster].where = (SLONG) ((SBYTE) IOBuffer[offset++]);
monster[whichmonster].wealth = (SLONG) ((SBYTE) IOBuffer[offset++]);
monster[whichmonster].sea = (SLONG) ((SBYTE) IOBuffer[offset++]);
offset++; // skip monster[].loseturn
}
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ treasure[whichtreasure].taken = (FLAG) ((SBYTE) IOBuffer[offset++]);
treasure[whichtreasure].possessor = (FLAG) ((SBYTE) IOBuffer[offset++]);
treasure[whichtreasure].possessortype = (SLONG) ((SBYTE) IOBuffer[offset++]);
treasure[whichtreasure].where = (SLONG) ((SBYTE) IOBuffer[offset++]);
}
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ sord[whichsord].taken = (FLAG) ((SBYTE) IOBuffer[offset++]);
sord[whichsord].possessor = (FLAG) ((SBYTE) IOBuffer[offset++]);
sord[whichsord].possessortype = (SLONG) ((SBYTE) IOBuffer[offset++]);
sord[whichsord].where = (SLONG) ((SBYTE) IOBuffer[offset++]);
}
for (whichcountry = 0; whichcountry <= 35; whichcountry++)
{ world[whichcountry].hero = (SLONG) ((SBYTE) IOBuffer[offset++]);
world[whichcountry].is = (FLAG) ((SBYTE) IOBuffer[offset++]);
}
// no need to read version string
Close(FileHandle);
// FileHandle = NULL;
strcpy(pathname, newpathname);
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ GT_SetGadgetAttrs(CycleGadgetPtr[whichhero], MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
}
GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
for (whichcountry = 0; whichcountry <= 65; whichcountry++)
{ for (whichslot = 0; whichslot <= SLOTS; whichslot++)
{ world[whichcountry].slot[whichslot] = FALSE;
} }
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].promoted == -1)
{ hero[whichhero].name = trueheroname[whichhero];
hero[whichhero].strength = HERO_STRENGTH;
hero[whichhero].moves = HERO_MOVES;
} else
{ hero[whichhero].name = jarl[hero[whichhero].promoted].name;
hero[whichhero].strength = jarl[hero[whichhero].promoted].strength;
hero[whichhero].moves = jarl[hero[whichhero].promoted].moves;
}
deselect_hero(whichhero, FALSE);
if (hero[whichhero].alive)
{ move_hero(whichhero, FALSE);
} else
{ remove_hero(whichhero, FALSE);
} }
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ jarl[whichjarl].recruitable = FALSE;
if (jarl[whichjarl].alive)
{ if (jarl[whichjarl].face == FACEUP)
{ revealjarl(whichjarl, FALSE);
} else
{ // assert(jarl[whichjarl].face == FACEDOWN);
hidejarl(whichjarl, FALSE);
}
move_jarl(whichjarl, FALSE);
} else
{ remove_jarl(whichjarl, FALSE);
} }
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ if (monster[whichmonster].alive)
{ move_monster(whichmonster, FALSE);
} else
{ remove_monster(whichmonster, FALSE);
} }
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if (treasure[whichtreasure].possessor == -1)
{ move_treasure(whichtreasure, FALSE);
} }
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if (sord[whichsord].possessor == -1)
{ move_sord(whichsord, FALSE);
} }
darken();
drawmap();
refreshcounters();
if (faxirides == -1)
{ faxirides = 0;
faxi_disappear();
}
strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_LOADED, "Loaded"));
strcat(saystring, " ");
strcat(saystring, pathname);
strcat(saystring, ".");
say(LOWER);
return(TRUE);
} }
MODULE void savegame(FLAG saveas)
{ SLONG offset = 12, whichhero, whichjarl, whichmonster, whichcountry,
whichtreasure, whichsord;
FLAG cont = TRUE;
TEXT newpathname[255];
BPTR FileHandle /* = NULL */ ;
strcpy(newpathname, pathname);
if (saveas || newpathname[0] == 0)
{ if
( AslRequestTags
( ASLRqPtr,
ASL_Hail, GetCatalogStr(li.li_Catalog, MSG_SAVE_GAME, "Save Game"),
ASL_FuncFlags, FILF_PATGAD | FILF_SAVE,
TAG_DONE
)
&& *(ASLRqPtr->rf_File) != 0
)
{ strcpy(newpathname, ASLRqPtr->rf_Dir);
AddPart(newpathname, ASLRqPtr->rf_File, 254);
} else
{ cont = FALSE;
} }
if (!cont)
{ return;
}
strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_SAVING, "Saving"));
strcat(saystring, " ");
strcat(saystring, newpathname);
strcat(saystring, "...");
say(LOWER);
if (!(FileHandle = Open(newpathname, MODE_NEWFILE)))
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_OPEN, "Can't open"));
strcat(saystring, " ");
strcat(saystring, newpathname);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FOR_WRITING, "for writing"));
strcat(saystring, "!");
say(LOWER);
anykey();
return;
}
/* write header
SAGA 1.0 *#%
012345678901
where * is NULL byte and # is turn and % is faxi rides */
strcpy(IOBuffer, "SAGA 1.0 ");
IOBuffer[10] = (SBYTE) turn;
IOBuffer[11] = (SBYTE) faxirides;
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ IOBuffer[offset++] = (SBYTE) hero[whichhero].control;
IOBuffer[offset++] = (SBYTE) hero[whichhero].alive;
IOBuffer[offset++] = (SBYTE) hero[whichhero].verydead;
IOBuffer[offset++] = (SBYTE) hero[whichhero].moves;
IOBuffer[offset++] = (SBYTE) hero[whichhero].god;
IOBuffer[offset++] = (SBYTE) hero[whichhero].rune;
IOBuffer[offset++] = (SBYTE) hero[whichhero].where;
IOBuffer[offset++] = (SBYTE) hero[whichhero].homewhere;
IOBuffer[offset++] = (SBYTE) hero[whichhero].promoted;
IOBuffer[offset++] = (SBYTE) hero[whichhero].wounded;
IOBuffer[offset++] = (UBYTE) (hero[whichhero].wealth / 256);
IOBuffer[offset++] = (UBYTE) (hero[whichhero].wealth % 256);
IOBuffer[offset++] = (UBYTE) (hero[whichhero].glory / 256);
IOBuffer[offset++] = (UBYTE) (hero[whichhero].glory % 256);
IOBuffer[offset++] = (UBYTE) (hero[whichhero].luck / 256);
IOBuffer[offset++] = (UBYTE) (hero[whichhero].luck % 256);
IOBuffer[offset++] = (SBYTE) hero[whichhero].sea;
IOBuffer[offset++] = (SBYTE) hero[whichhero].loseturn;
IOBuffer[offset++] = (SBYTE) hero[whichhero].maidens;
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ IOBuffer[offset++] = (SBYTE) jarl[whichjarl].where;
IOBuffer[offset++] = (SBYTE) jarl[whichjarl].homewhere;
IOBuffer[offset++] = (SBYTE) jarl[whichjarl].face;
IOBuffer[offset++] = (SBYTE) jarl[whichjarl].hero;
IOBuffer[offset++] = (SBYTE) jarl[whichjarl].taken;
IOBuffer[offset++] = (SBYTE) jarl[whichjarl].sea;
IOBuffer[offset++] = (SBYTE) jarl[whichjarl].loseturn;
IOBuffer[offset++] = (SBYTE) jarl[whichjarl].alive;
}
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ IOBuffer[offset++] = (SBYTE) monster[whichmonster].taken;
IOBuffer[offset++] = (SBYTE) monster[whichmonster].alive;
IOBuffer[offset++] = (SBYTE) monster[whichmonster].where;
IOBuffer[offset++] = (SBYTE) monster[whichmonster].wealth;
IOBuffer[offset++] = (SBYTE) monster[whichmonster].sea;
IOBuffer[offset++] = (SBYTE) 0; // skip monster loseturn
}
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].taken;
IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].possessor;
IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].possessortype;
IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].where;
}
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ IOBuffer[offset++] = (SBYTE) sord[whichsord].taken;
IOBuffer[offset++] = (SBYTE) sord[whichsord].possessor;
IOBuffer[offset++] = (SBYTE) sord[whichsord].possessortype;
IOBuffer[offset++] = (SBYTE) sord[whichsord].where;
}
for (whichcountry = 0; whichcountry <= 35; whichcountry++)
{ IOBuffer[offset++] = (SBYTE) world[whichcountry].hero;
IOBuffer[offset++] = (SBYTE) world[whichcountry].is;
}
if (Write(FileHandle, IOBuffer, offset) != offset)
{ Close(FileHandle);
// FileHandle = NULL;
strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_WRITE_TO, "Can't write to"));
strcat(saystring, " ");
strcat(saystring, newpathname);
strcat(saystring, "!");
say(LOWER);
anykey();
return;
}
/* write version string */
Write(FileHandle, VERSION, strlen(VERSION));
Close(FileHandle);
// FileHandle = NULL;
strcpy(pathname, newpathname);
strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_SAVED, "Saved"));
strcat(saystring, " ");
strcat(saystring, pathname);
strcat(saystring, ".");
say(LOWER);
// no need for anykey(), as there is one when we return anyway.
}
MODULE SLONG odin_tyr(SLONG whichhero, FLAG attacking)
{ SLONG whichjarl, whichprayer;
SLONG adjustment = 0;
if (hero[whichhero].god == ODIN)
{ hero[whichhero].god = -1;
whichprayer = d6();
strcpy(saystring, "Odin");
if (whichprayer == 1)
{ adjustment = -3;
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_E_B_A_3_T_T_S, "'s enemy by adding 3 to their strength"));
strcat(saystring, ".");
} elif (whichprayer == 2)
{ adjustment = -1;
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SENDS_A_WOLF_TO_AID_HERO, "sends a wolf to aid hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_ENEMY, "'s enemy"));
strcat(saystring, ".");
} elif (whichprayer == 3)
{ strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_R_A_S_B_H_T_O_T_B, "'s ravens are sent by him to observe the battle"));
strcat(saystring, ".");
} elif (whichprayer == 4)
{ adjustment = 1;
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SENDS_A_WOLF_TO_AID_HERO, "sends a wolf to aid hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, ".");
} elif (whichprayer == 5)
{ adjustment = 3;
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_3_TO_HIS_STRENGTH, "by adding 3 to his strength"));
strcat(saystring, ".");
} else
{ // assert(whichprayer == 6);
adjustment = 5;
hero[whichhero].glory += 3;
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_INTERVENES_PERSONALLY, "intervenes personally"));
strcat(saystring, ".");
}
say(LOWER);
anykey();
} elif (hero[whichhero].god == TYR)
{ hero[whichhero].god = -1;
whichprayer = d6();
strcpy(saystring, "Tyr ");
if (whichprayer == 1)
{ adjustment = -1;
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_E_B_A_1_T_T_S, "'s enemy by adding 1 to their strength"));
strcat(saystring, ".");
} elif (whichprayer == 2 || whichprayer == 3)
{ strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_D_T_T_F_I_B_F, "decides that the fight is balanced fairly"));
strcat(saystring, ".");
} elif (whichprayer == 4)
{ adjustment = 1;
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_1_TO_HIS_STRENGTH, "by adding 1 to his strength"));
strcat(saystring, ".");
} elif (whichprayer == 5)
{ adjustment = 2;
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_2_TO_HIS_STRENGTH, "by adding 2 to his strength"));
strcat(saystring, ".");
} else
{ assert(whichprayer == 6);
adjustment = 1; // for the hero himself
if (attacking)
{ for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ adjustment++;
} } }
else
{ for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].defending)
{ adjustment++;
} } }
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_B_A_1_T_T_S_O_E_P_O_H_S, "by adding 1 to the strength of each person on his side"));
strcat(saystring, ".");
}
say(LOWER);
anykey();
}
return(adjustment);
}
MODULE void pray(SLONG whichhero)
{ SLONG decision;
decision = d6();
if (decision == 1 || (hero[whichhero].rune == AMSIR && decision == 2))
{ gods(whichhero);
} }
MODULE void amiga_rout(SLONG routedtype, SLONG routed)
{ SLONG decision, whichmove, moves;
FLAG freemove;
if (routedtype == HERO)
{ hero[routed].routed = TRUE;
} elif (routedtype == JARL)
{ jarl[routed].routed = TRUE;
}
moves = getmoves(routedtype, routed, FALSE);
if (moves < 1)
{ return;
}
if (routedtype == HERO || routedtype == JARL)
{ saywho(routedtype, routed, FALSE, FALSE);
} else
{ // assert(routedtype == MONSTER);
strcpy(saystring, monstertypes[monster[routed].species]);
strcat(saystring, " ");
strcat(saystring, monster[routed].name);
strcat(saystring, " ");
}
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_BEING_ROUTED, "is being routed"));
strcat(saystring, "...");
say(LOWER);
if (routedtype == HERO)
{ freemove = FALSE;
select_hero(routed, TRUE);
for (whichmove = 1; whichmove <= moves; whichmove++)
{ do
{ decision = rand() % (CONNECTIONS + 1);
} while (world[hero[routed].where].connection[decision] == -1);
if
( hero[routed].sea == BAD
&& ( world[world[hero[routed].where].connection[decision]].type == SEA
|| world[world[hero[routed].where].connection[decision]].type == ISLE
) )
{ whichmove--;
} else
{ unslot_hero(routed);
hero[routed].where = world[hero[routed].where].connection[decision];
move_hero(routed, TRUE);
if (hero[routed].sea == GOOD)
{ if (!freemove)
{ if
( world[hero[routed].where].type == SEA
|| world[hero[routed].where].type == ISLE
)
{ freemove = TRUE;
} }
else
{ if
( world[hero[routed].where].type == LAND
)
{ freemove = FALSE;
} else
{ whichmove--;
} } } } }
deselect_hero(routed, TRUE);
} elif (routedtype == JARL)
{ select_jarl(routed, TRUE);
for (whichmove = 1; whichmove <= moves; whichmove++)
{ do
{ decision = rand() % (CONNECTIONS + 1);
} while (world[jarl[routed].where].connection[decision] == -1);
if
( jarl[routed].sea == BAD
&& ( world[world[jarl[routed].where].connection[decision]].type == SEA
|| world[world[jarl[routed].where].connection[decision]].type == ISLE
) )
{ whichmove--;
} else
{ unslot_jarl(routed);
jarl[routed].where = world[jarl[routed].where].connection[decision];
move_jarl(routed, TRUE);
} }
deselect_jarl(routed, TRUE);
} elif (routedtype == MONSTER)
{ // select_monster(routed);
for (whichmove = 1; whichmove <= moves; whichmove++)
{ do
{ decision = rand() % (CONNECTIONS + 1);
} while (world[monster[routed].where].connection[decision] == -1);
if
( monster[routed].sea == BAD
&& ( world[world[monster[routed].where].connection[decision]].type == SEA
|| world[world[monster[routed].where].connection[decision]].type == ISLE
) )
{ whichmove--;
} else
{ unslot_monster(routed);
monster[routed].where = world[monster[routed].where].connection[decision];
move_monster(routed, TRUE);
} }
// deselect_monster(routed);
} }
MODULE void human_rout(SLONG routedtype, SLONG routed, SLONG routerhero)
{ SLONG country,
oldcountry = -1,
moves,
whichconnection,
whichmove;
FLAG legal, freemove;
moves = getmoves(routedtype, routed, FALSE);
if (moves == 0)
{ return;
}
if (routedtype == HERO)
{ select_hero(routed, TRUE);
oldcountry = hero[routed].where;
} elif (routedtype == JARL)
{ select_jarl(routed, TRUE);
oldcountry = jarl[routed].where;
} elif (routedtype == MONSTER)
{ // select_monster(routed);
oldcountry = monster[routed].where;
}
whichmove = 1;
freemove = FALSE;
do
{ saywho(HERO, routerhero, TRUE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ROUT, "rout"));
strcat(saystring, " ");
stcl_d(numberstring, whichmove);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
strcat(saystring, " ");
stcl_d(numberstring, moves);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FOR, "for"));
if (routedtype == HERO || routedtype == JARL)
{ saywho(routedtype, routed, FALSE, TRUE);
} else
{ // assert(routedtype == MONSTER);
strcat(saystring, " ");
strcat(saystring, monstertypes[monster[routed].species]);
strcat(saystring, " ");
strcat(saystring, monster[routed].name);
}
strcat(saystring, "?");
say(LOWER);
do
{ country = getevent(COUNTRY, NULL);
} while ((country < -3 || country > 65) || country == -1);
if (country == -3)
{ break;
} elif (country == -2)
{ whichmove = 1;
if (routedtype == HERO)
{ unslot_hero(routed);
hero[routed].where = oldcountry;
move_hero(routed, TRUE);
freemove = FALSE;
} elif (routedtype == JARL)
{ unslot_jarl(routed);
jarl[routed].where = oldcountry;
move_jarl(routed, TRUE);
} else
{ // assert(routedtype == MONSTER);
unslot_monster(routed);
monster[routed].where = oldcountry;
move_monster(routed, TRUE);
} }
else
{ legal = FALSE;
for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
{ if
( (routedtype == HERO && world[hero[routed].where].connection[whichconnection] == country)
|| (routedtype == JARL && world[jarl[routed].where].connection[whichconnection] == country)
|| (routedtype == MONSTER && world[monster[routed].where].connection[whichconnection] == country)
)
{ legal = TRUE;
break; // for speed
} }
if (legal)
{ if (routedtype == HERO)
{ if
( hero[routed].sea == BAD
&& ( world[country].type == SEA
|| world[country].type == ISLE
) )
{ legal = FALSE;
saywho(HERO, routed, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
strcat(saystring, ".");
say(LOWER);
anykey();
} }
elif (routedtype == JARL)
{ if
( jarl[routed].sea == BAD
&& ( world[country].type == SEA
|| world[country].type == ISLE
) )
{ legal = FALSE;
saywho(JARL, routed, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
strcat(saystring, ".");
say(LOWER);
anykey();
} }
elif (routedtype == MONSTER)
{ if
( monster[routed].sea == BAD
&& ( world[country].type == SEA
|| world[country].type == ISLE
) )
{ legal = FALSE;
strcat(saystring, monstertypes[monster[routed].species]);
strcat(saystring, " ");
strcat(saystring, monster[routed].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
strcat(saystring, ".");
say(LOWER);
anykey();
} } }
if (legal)
{ if (routedtype == HERO)
{ unslot_hero(routed);
hero[routed].where = country;
move_hero(routed, TRUE);
if (hero[routed].sea == GOOD)
{ if (!freemove)
{ if
( world[hero[routed].where].type == SEA
|| world[hero[routed].where].type == ISLE
)
{ freemove = TRUE;
}
whichmove++;
} else
{ if
( world[hero[routed].where].type == LAND
)
{ freemove = FALSE;
whichmove++;
} } } }
elif (routedtype == JARL)
{ unslot_jarl(routed);
jarl[routed].where = country;
move_jarl(routed, TRUE);
} else
{ // assert(routedtype == MONSTER);
unslot_monster(routed);
monster[routed].where = country;
move_monster(routed, TRUE);
}
whichmove++;
} else
{ ; // DisplayBeep(ScreenPtr);
} }
} while (whichmove <= moves);
if (routedtype == HERO)
{ deselect_hero(routed, TRUE);
} elif (routedtype == JARL)
{ deselect_jarl(routed, TRUE);
} }
MODULE SLONG getmoves(SLONG countertype, SLONG whichcounter, FLAG freyfaxi)
{ SLONG moves;
if (countertype == HERO)
{ moves = hero[whichcounter].moves;
} elif (countertype == MONSTER)
{ // assert(!freyfaxi);
moves = monster[whichcounter].moves;
} else
{ assert(countertype == JARL);
moves = jarl[whichcounter].moves;
}
if (freyfaxi)
{ moves *= 2;
}
if
( countertype != MONSTER // so dragon's don't use magic treasures
&& treasure[MAGICSHIRT].possessortype == countertype
&& treasure[MAGICSHIRT].possessor == whichcounter
)
{ // assert(treasure[MAGICSHIRT].where == -1);
moves++;
}
if (countertype == HERO && hero[whichcounter].rune == EON)
{ moves++;
}
if
( (countertype == HERO && hero[whichcounter].loseturn)
|| (countertype == JARL && jarl[whichcounter].loseturn)
)
{ moves = 0;
}
/* If you are stuck at sea or on an island, and can't travel
by sea, then you can't move at all that turn. */
if
( countertype == HERO
&& hero[whichcounter].sea == BAD
&& ( world[hero[whichcounter].where].type == SEA
|| world[hero[whichcounter].where].type == ISLE
) )
{ moves = 0;
} elif
( countertype == JARL
&& jarl[whichcounter].sea == BAD
&& ( world[jarl[whichcounter].where].type == SEA
|| world[jarl[whichcounter].where].type == ISLE
) )
{ moves = 0;
} elif
( countertype == MONSTER
&& monster[whichcounter].sea == BAD
&& ( world[monster[whichcounter].where].type == SEA
|| world[monster[whichcounter].where].type == ISLE
) )
{ moves = 0;
}
return(moves);
}
MODULE void faxi_disappear(void)
{ if (faxirides == 0) // faxi disappears
{ treasure[FREYFAXI].possessortype = -1; // noone
treasure[FREYFAXI].possessor = -1; // noone
treasure[FREYFAXI].where = -1; // nowhere
// frey faxi won't be on the board at the moment anyway
faxirides = -1; // so it only disappears once
} }
MODULE void thor(SLONG whichhero)
{ SLONG whichprayer;
if (hero[whichhero].god == THOR)
{ hero[whichhero].god = -1;
whichprayer = d6();
strcpy(saystring, "Thor ");
if (whichprayer >= 1 && whichprayer <= 3)
{ strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_DECIDES_THAT_HERO, "decides that hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_DESERVES_NO_REWARD, "deserves no reward"));
strcat(saystring, ".");
} elif (whichprayer == 4 || whichprayer == 5)
{ hero[whichhero].glory++;
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_REWARDS_HERO, "rewards hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_B_S_T_H_G_1_G, "by speaking to him, granting 1 glory"));
strcat(saystring, ".");
} else
{ // assert(whichprayer == 6);
hero[whichhero].glory += 2;
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HONOURS_HERO, "honours hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_B_E_W_H_G_2_G, "by eating with him, granting 2 glory"));
strcat(saystring, ".");
}
say(LOWER);
anykey();
} }
MODULE void dospell(SLONG spell, SLONG caster)
{ SLONG whichhero, whichjarl, whichmonster;
if (spell == HAGALL || spell == JARA || d6() <= 3) // if it's a spell which doesn't have a saving throw, or the saving throw is missed
{ strcat(saystring, ".");
say(LOWER);
anykey();
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if
( hero[whichhero].control != NONE
&& hero[whichhero].alive
&& hero[whichhero].where == monster[caster].where
)
{ if (hero[whichhero].rune == SYGIL && d6() <= 3)
{ strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
strcat(saystring, " ");
strcat(saystring, hero[whichhero].name);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_RUNE_PROTECTS_HIM, "'s rune protects him"));
strcat(saystring, ".");
say(LOWER);
anykey();
} else
{ if (spell == HAGALL)
{ hero[whichhero].hagall = TRUE;
hero[whichhero].sea = BAD;
} elif (spell == JARA)
{ hero[whichhero].loseturn = TRUE;
} elif (spell == NIED)
{ hero[whichhero].loseturn = TRUE;
hero[whichhero].attacking = FALSE;
deselect_hero(whichhero, TRUE);
} elif (spell == WYNN)
{ hero[whichhero].glory -= 2;
if (hero[whichhero].glory < 0)
{ hero[whichhero].glory = 0;
}
amiga_rout(HERO, whichhero);
hero[whichhero].attacking = FALSE;
deselect_hero(whichhero, TRUE);
} elif (spell == YR)
{ wound(MONSTER, caster, -1, HERO, whichhero, whichhero);
hero[whichhero].attacking = FALSE;
deselect_hero(whichhero, TRUE);
} } } }
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if
( jarl[whichjarl].alive
&& jarl[whichjarl].where == monster[caster].where
)
{ if (spell == HAGALL)
{ jarl[whichjarl].hagall = TRUE;
jarl[whichjarl].sea = BAD;
} elif (spell == JARA)
{ jarl[whichjarl].loseturn = TRUE;
} elif (spell == NIED)
{ jarl[whichjarl].loseturn = TRUE;
jarl[whichjarl].attacking = FALSE;
deselect_jarl(whichjarl, TRUE);
} elif (spell == WYNN)
{ amiga_rout(JARL, whichjarl);
jarl[whichjarl].attacking = FALSE;
deselect_jarl(whichjarl, TRUE);
} elif (spell == YR)
{ if (jarl[whichjarl].face == FACEUP)
{ wound(MONSTER, caster, -1, JARL, whichjarl, jarl[whichjarl].hero);
jarl[whichjarl].attacking = FALSE;
deselect_jarl(whichjarl, TRUE);
} } } }
if (spell == HAGALL)
{ for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ if
( monster[whichmonster].alive
&& monster[whichmonster].where == monster[caster].where
)
{ monster[whichmonster].hagall = TRUE;
monster[whichmonster].sea = BAD;
} } } }
else
{ strcat(saystring, ", ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BUT_IT_FIZZLES, "but it fizzles"));
strcat(saystring, "!");
say(LOWER);
anykey();
} }
MODULE void cast(SLONG caster, SLONG whichspell)
{ strcpy(saystring, monstertypes[monster[caster].species]);
strcat(saystring, " ");
strcat(saystring, monster[caster].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CASTS, "casts"));
strcat(saystring, " ");
switch(whichspell)
{
case HAGALL:
strcat(saystring, "Hagall (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAIL_SLOW, "hail/slow"));
strcat(saystring, ")");
dospell(HAGALL, caster);
break;
case IS:
world[monster[caster].where].is = TRUE;
darken();
strcat(saystring, "Is (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ICE, "ice"));
strcat(saystring, ").");
say(LOWER);
anykey();
break;
case JARA:
strcat(saystring, "Jara (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LOSE_NEXT_TURN, "lose next turn"));
strcat(saystring, ")");
dospell(JARA, caster);
break;
case NIED:
strcat(saystring, "Nied (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_N_R_A_L_N_T, "no result and lose next turn"));
strcat(saystring, ")");
dospell(NIED, caster);
break;
case WYNN:
strcat(saystring, "Wynn (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FLEEING, "fleeing"));
strcat(saystring, ")");
dospell(WYNN, caster);
break;
case YR:
strcat(saystring, "Yr (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_WOUNDING, "wounding"));
strcat(saystring, ")");
dospell(YR, caster);
break;
default:
// assert(0);
break;
} }
MODULE void darken(void)
{ SLONG whichcountry, colour;
for (whichcountry = 0; whichcountry <= 35; whichcountry++)
{ if (whichcountry >= 9 && whichcountry <= 11)
{ colour = whichcountry + 80;
} else
{ colour = whichcountry + 8;
}
if (world[whichcountry].is)
{ SetRGB4(&ScreenPtr->ViewPort, colour, 12, 12, 12); // light grey ice
} elif (world[whichcountry].hero != -1)
{ SetRGB4
( &ScreenPtr->ViewPort,
colour,
herocolour[world[whichcountry].hero].red,
herocolour[world[whichcountry].hero].green,
herocolour[world[whichcountry].hero].blue
);
} else
{ SetRGB4
( &ScreenPtr->ViewPort,
colour,
taxcolours[world[whichcountry].tax].red,
taxcolours[world[whichcountry].tax].green,
taxcolours[world[whichcountry].tax].blue
);
} } }
MODULE SLONG checkcountry(WORD mousex, WORD mousey)
{ SLONG country;
country = ReadPixel(MainWindowPtr->RPort, mousex, mousey);
if (country == 80 || country == 81 || country == 91)
{ country = 11; // Scandia
} elif (country == 82 || country == 83)
{ country = 30; // Pictland
} elif (country == 84 || country == 85)
{ country = 31; // Hebrides
} elif (country == 89)
{ country = 9; // Suder Gotland
} elif (country == 90)
{ country = 10; // Juteland
} else
{ country -= 8;
}
return(country);
}
MODULE void infowindow(SLONG countertype, SLONG whichcounter)
{ SLONG lines,
leftlines = 0,
rightlines = 0,
oldwhichline,
whichline,
whichcountry,
whichjarl,
whichhero,
whichtreasure,
whichsord,
wide,
whichmonster;
FLAG counterrow = FALSE,
done = FALSE,
ok;
ULONG class;
UWORD code, qual;
struct IntuiMessage* MsgPtr;
if (countertype == HERO)
{ strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_HERO_NAME, "Hero Name"));
strcat(line[LEFTSIDE][0], ":");
pad(line[LEFTSIDE][0]);
strcat(line[LEFTSIDE][0], hero[whichcounter].name);
strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_CONTROL, "Control"));
strcat(line[LEFTSIDE][1], ":");
pad(line[LEFTSIDE][1]);
if (hero[whichcounter].control == HUMAN)
{ strcat(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_HUMAN, "Human"));
} else
{ // assert(hero[whichcounter].control == AMIGA);
strcat(line[LEFTSIDE][1], "Amiga");
}
strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_COMBAT_STRENGTH, "Combat Strength"));
strcat(line[LEFTSIDE][2], ":");
pad(line[LEFTSIDE][2]);
stcl_d(numberstring, hero[whichcounter].strength);
strcat(line[LEFTSIDE][2], numberstring);
strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_MOVEMENT_FACTOR, "Movement Factor"));
strcat(line[LEFTSIDE][3], ":");
pad(line[LEFTSIDE][3]);
stcl_d(numberstring, hero[whichcounter].moves);
strcat(line[LEFTSIDE][3], numberstring);
strcpy(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_GLORY, "Glory"));
strcat(line[LEFTSIDE][4], ":");
pad(line[LEFTSIDE][4]);
stcl_d(numberstring, hero[whichcounter].glory);
strcat(line[LEFTSIDE][4], numberstring);
strcpy(line[LEFTSIDE][5], GetCatalogStr(li.li_Catalog, MSG_LUCK, "Luck"));
strcat(line[LEFTSIDE][5], ":");
pad(line[LEFTSIDE][5]);
stcl_d(numberstring, hero[whichcounter].luck);
strcat(line[LEFTSIDE][5], numberstring);
strcpy(line[LEFTSIDE][6], GetCatalogStr(li.li_Catalog, MSG_WEALTH, "Wealth"));
strcat(line[LEFTSIDE][6], ":");
pad(line[LEFTSIDE][6]);
stcl_d(numberstring, hero[whichcounter].wealth);
strcat(line[LEFTSIDE][6], numberstring);
print_location(hero[whichcounter].where, 7);
strcpy(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_HOMELAND, "Homeland"));
strcat(line[LEFTSIDE][8], ":");
pad(line[LEFTSIDE][8]);
strcat(line[LEFTSIDE][8], world[hero[whichcounter].homewhere].name);
strcat(line[LEFTSIDE][8], " (");
stcl_d(numberstring, world[hero[whichcounter].homewhere].tax);
strcat(line[LEFTSIDE][8], numberstring);
strcat(line[LEFTSIDE][8], ")");
strcpy(line[LEFTSIDE][9], GetCatalogStr(li.li_Catalog, MSG_MAIDENS, "Maidens"));
strcat(line[LEFTSIDE][9], ":");
pad(line[LEFTSIDE][9]);
stcl_d(numberstring, hero[whichcounter].maidens);
strcat(line[LEFTSIDE][9], numberstring);
strcpy(line[LEFTSIDE][10], GetCatalogStr(li.li_Catalog, MSG_RUNE, "Rune"));
strcat(line[LEFTSIDE][10], ":");
pad(line[LEFTSIDE][10]);
if (hero[whichcounter].rune == -1)
{ strcat(line[LEFTSIDE][10], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
} else
{ strcat(line[LEFTSIDE][10], runename[hero[whichcounter].rune]);
}
strcpy(line[LEFTSIDE][11], GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
strcat(line[LEFTSIDE][11], ":");
pad(line[LEFTSIDE][11]);
ok = FALSE;
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if
( sord[whichsord].possessortype == HERO
&& sord[whichsord].possessor == whichcounter
)
{ ok = TRUE;
counterrow = TRUE;
strcat(line[LEFTSIDE][11], sord[whichsord].name);
break; // for speed
} }
if (!ok)
{ strcat(line[LEFTSIDE][11], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
}
strcpy(line[LEFTSIDE][12], GetCatalogStr(li.li_Catalog, MSG_WOUNDED, "Wounded"));
strcat(line[LEFTSIDE][12], "?");
pad(line[LEFTSIDE][12]);
if (hero[whichcounter].wounded)
{ strcat(line[LEFTSIDE][12], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
} else
{ strcat(line[LEFTSIDE][12], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
}
print_paralyzed(hero[whichcounter].loseturn, 13);
print_hagall(hero[whichcounter].hagall, 14);
print_sea(hero[whichcounter].sea, 15);
print_routed(hero[whichcounter].routed, 16);
leftlines = 17; // counting from 1
strcpy(line[RIGHTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_RECRUITED_JARLS, "Recruited Jarls"));
strcat(line[RIGHTSIDE][0], ":");
whichline = oldwhichline = 1; // whichline always points to the NEXT line.
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichcounter)
{ strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], jarl[whichjarl].name);
strcat(line[RIGHTSIDE][whichline], " (");
stcl_d(numberstring, jarl[whichjarl].strength);
strcat(line[RIGHTSIDE][whichline], numberstring);
strcat(line[RIGHTSIDE][whichline], "-");
stcl_d(numberstring, jarl[whichjarl].moves);
strcat(line[RIGHTSIDE][whichline], numberstring);
strcat(line[RIGHTSIDE][whichline], ")");
whichline++;
} }
if (whichline == oldwhichline)
{ strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
whichline++;
}
strcpy(line[RIGHTSIDE][whichline], "");
whichline++;
strcpy(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_CONQUERED_KINGDOMS, "Conquered Kingdoms"));
strcat(line[RIGHTSIDE][whichline], ":");
whichline++;
oldwhichline = whichline;
for (whichcountry = 0; whichcountry <= 35; whichcountry++)
{ if (world[whichcountry].hero == whichcounter)
{ strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], world[whichcountry].name);
strcat(line[RIGHTSIDE][whichline], " (");
stcl_d(numberstring, world[whichcountry].tax);
strcat(line[RIGHTSIDE][whichline], numberstring);
strcat(line[RIGHTSIDE][whichline], ")");
whichline++;
} }
if (whichline == oldwhichline)
{ strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
whichline++;
}
strcpy(line[RIGHTSIDE][whichline], "");
whichline++;
strcpy(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_MAGIC_TREASURES, "Magic Treasures"));
strcat(line[RIGHTSIDE][whichline], ":");
whichline++;
oldwhichline = whichline;
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if (treasure[whichtreasure].possessortype == HERO
&& treasure[whichtreasure].possessor == whichcounter
)
{ counterrow = TRUE;
strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], treasure[whichtreasure].name);
if (whichtreasure == FREYFAXI)
{ strcat(line[RIGHTSIDE][whichline], " (");
stcl_d(numberstring, faxirides);
strcat(line[RIGHTSIDE][whichline], numberstring);
strcat(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_RIDES2, "rides"));
strcat(line[RIGHTSIDE][whichline], ")");
}
whichline++;
} }
if (whichline == oldwhichline)
{ strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
whichline++;
}
rightlines = whichline;
} elif (countertype == MONSTER)
{ strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_MONSTER_NAME, "Monster Name"));
strcat(line[LEFTSIDE][0], ":");
pad(line[LEFTSIDE][0]);
strcat(line[LEFTSIDE][0], monster[whichcounter].name);
strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_MONSTER_SPECIES, "Monster Species"));
strcat(line[LEFTSIDE][1], ":");
pad(line[LEFTSIDE][1]);
strcat(line[LEFTSIDE][1], monstertypes[monster[whichcounter].species]);
strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_COMBAT_STRENGTH, "Combat Strength"));
strcat(line[LEFTSIDE][2], ":");
pad(line[LEFTSIDE][2]);
stcl_d(numberstring, monster[whichcounter].strength);
strcat(line[LEFTSIDE][2], numberstring);
strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_MOVEMENT_FACTOR, "Movement Factor"));
strcat(line[LEFTSIDE][3], ":");
pad(line[LEFTSIDE][3]);
stcl_d(numberstring, monster[whichcounter].moves);
strcat(line[LEFTSIDE][3], numberstring);
strcpy(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_WEALTH, "Wealth"));
strcat(line[LEFTSIDE][4], ":");
pad(line[LEFTSIDE][4]);
stcl_d(numberstring, monster[whichcounter].wealth);
strcat(line[LEFTSIDE][4], numberstring);
print_location(monster[whichcounter].where, 5);
print_hagall(monster[whichcounter].hagall, 6);
print_sea(monster[whichcounter].sea, 7);
strcpy(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_TREASURE, "Treasure"));
strcat(line[LEFTSIDE][8], "?");
pad(line[LEFTSIDE][8]);
ok = FALSE;
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if
( treasure[whichtreasure].possessortype == MONSTER
&& treasure[whichtreasure].possessor == whichcounter
)
{ ok = TRUE;
break;
} }
if (ok)
{ strcat(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
} else
{ strcat(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
}
leftlines = 9; // counting from 1
rightlines = 0;
} elif (countertype == JARL)
{ strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_JARL_NAME, "Jarl Name"));
strcat(line[LEFTSIDE][0], ":");
pad(line[LEFTSIDE][0]);
if (jarl[whichcounter].face == FACEUP)
{ strcat(line[LEFTSIDE][0], jarl[whichcounter].name);
} else
{ strcat(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_UNKNOWN, "Unknown"));
}
strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
strcat(line[LEFTSIDE][1], ":");
pad(line[LEFTSIDE][1]);
if (jarl[whichcounter].hero == -1)
{ strcat(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_KING_NONE, "None"));
} else
{ strcat(line[LEFTSIDE][1], hero[jarl[whichcounter].hero].name);
}
strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_COMBAT_STRENGTH, "Combat Strength"));
strcat(line[LEFTSIDE][2], ":");
pad(line[LEFTSIDE][2]);
if (jarl[whichcounter].face == FACEUP)
{ stcl_d(numberstring, jarl[whichcounter].strength);
strcat(line[LEFTSIDE][2], numberstring);
} else
{ // assert(jarl[whichcounter].face == FACEDOWN);
strcat(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_UNKNOWN, "Unknown"));
}
strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_MOVEMENT_FACTOR, "Movement Factor"));
strcat(line[LEFTSIDE][3], ":");
pad(line[LEFTSIDE][3]);
if (jarl[whichcounter].face == FACEUP)
{ stcl_d(numberstring, jarl[whichcounter].moves);
strcat(line[LEFTSIDE][3], numberstring);
} else
{ // assert(jarl[whichcounter].face == FACEDOWN);
strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_UNKNOWN, "Unknown"));
}
strcpy(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_WEALTH, "Wealth"));
strcat(line[LEFTSIDE][4], ":");
pad(line[LEFTSIDE][4]);
stcl_d(numberstring, jarl[whichcounter].wealth);
strcat(line[LEFTSIDE][4], numberstring);
print_location(jarl[whichcounter].where, 5);
strcpy(line[LEFTSIDE][6], GetCatalogStr(li.li_Catalog, MSG_HOMELAND, "Homeland"));
strcat(line[LEFTSIDE][6], ":");
pad(line[LEFTSIDE][6]);
strcat(line[LEFTSIDE][6], world[jarl[whichcounter].homewhere].name);
strcat(line[LEFTSIDE][6], " (");
stcl_d(numberstring, world[jarl[whichcounter].homewhere].tax);
strcat(line[LEFTSIDE][6], numberstring);
strcat(line[LEFTSIDE][6], ")");
strcpy(line[LEFTSIDE][7], GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
strcat(line[LEFTSIDE][7], ":");
pad(line[LEFTSIDE][7]);
ok = FALSE;
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if
( sord[whichsord].possessortype == JARL
&& sord[whichsord].possessor == whichcounter
)
{ ok = TRUE;
counterrow = TRUE;
strcat(line[LEFTSIDE][7], sord[whichsord].name);
break; // for speed
} }
if (!ok)
{ strcat(line[LEFTSIDE][7], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
}
print_paralyzed(jarl[whichcounter].loseturn, 8);
print_hagall(jarl[whichcounter].hagall, 9);
print_sea(jarl[whichcounter].sea, 10);
print_routed(jarl[whichcounter].routed, 11);
leftlines = 12; // counting from 1
strcpy(line[RIGHTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_MAGIC_TREASURES, "Magic Treasures"));
strcat(line[RIGHTSIDE][0], ":");
whichline = oldwhichline = 1; // whichline always points to the NEXT line.
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if (treasure[whichtreasure].possessortype == JARL
&& treasure[whichtreasure].possessor == whichcounter
)
{ counterrow = TRUE;
strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], treasure[whichtreasure].name);
if (whichtreasure == FREYFAXI)
{ strcat(line[RIGHTSIDE][whichline], " (");
stcl_d(numberstring, faxirides);
strcat(line[RIGHTSIDE][whichline], numberstring);
strcat(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_RIDES2, "rides"));
strcat(line[RIGHTSIDE][whichline], ")");
}
whichline++;
} }
if (whichline == oldwhichline)
{ strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
whichline++;
}
rightlines = whichline;
} elif (countertype == TREASURE)
{ strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_TREASURE_NAME, "Treasure Name"));
strcat(line[LEFTSIDE][0], ":");
pad(line[LEFTSIDE][0]);
strcat(line[LEFTSIDE][0], treasure[whichcounter].name);
print_location(treasure[whichcounter].where, 1);
strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_RIDES, "Rides"));
strcat(line[LEFTSIDE][2], ":");
if (whichcounter == FREYFAXI)
{ // assert(faxirides != -1);
stcl_d(numberstring, faxirides);
strcat(line[LEFTSIDE][2], numberstring);
} else
{ strcat(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_N_A, "n/a"));
}
leftlines = 3;
rightlines = 0;
} elif (countertype == KINGDOM)
{ strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_KINGDOM_NAME, "Kingdom Name"));
strcat(line[LEFTSIDE][0], ":");
pad(line[LEFTSIDE][0]);
strcat(line[LEFTSIDE][0], world[whichcounter].name);
strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_KING, "King"));
strcat(line[LEFTSIDE][1], ":");
pad(line[LEFTSIDE][1]);
if (world[whichcounter].hero == -1)
{ strcat(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_KING_NONE, "None"));
} else
{ strcat(line[LEFTSIDE][1], hero[world[whichcounter].hero].name);
}
strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_TAXATION_FACTOR, "Taxation Factor"));
strcat(line[LEFTSIDE][2], ":");
pad(line[LEFTSIDE][2]);
stcl_d(numberstring, world[whichcounter].tax);
strcat(line[LEFTSIDE][2], numberstring);
strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_TYPE, "Type"));
strcat(line[LEFTSIDE][3], ":");
pad(line[LEFTSIDE][3]);
if (world[whichcounter].type == LAND)
{ strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_LAND, "Land"));
} elif (world[whichcounter].type == ISLE)
{ strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_ISLAND, "Island"));
} elif (world[whichcounter].type == SEA)
{ strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_SEA, "Sea"));
} else
{ // assert(world[whichcounter].type == PENINSULA);
strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_PENINSULA, "Peninsula"));
}
strcpy(line[LEFTSIDE][4], "Is (");
strcat(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_ICE, "ice"));
strcat(line[LEFTSIDE][4], ")?");
pad(line[LEFTSIDE][4]);
if (world[whichcounter].is)
{ strcat(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
} else
{ strcat(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
}
leftlines = 5; // counting from 1
strcpy(line[RIGHTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_CONTENTS, "Contents"));
strcat(line[RIGHTSIDE][0], ":");
whichline = oldwhichline = 1; // whichline always points to the NEXT line.
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].alive && hero[whichhero].where == whichcounter)
{ strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
strcat(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], hero[whichhero].name);
strcat(line[RIGHTSIDE][whichline], " (");
stcl_d(numberstring, hero[whichhero].strength);
strcat(line[RIGHTSIDE][whichline], numberstring);
strcat(line[RIGHTSIDE][whichline], "-");
stcl_d(numberstring, hero[whichhero].moves);
strcat(line[RIGHTSIDE][whichline], numberstring);
strcat(line[RIGHTSIDE][whichline], ")");
whichline++;
} }
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].where == whichcounter)
{ strcpy(line[RIGHTSIDE][whichline], " ");
if (jarl[whichjarl].face == FACEUP)
{ strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_JARL, "Jarl"));
strcat(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], jarl[whichjarl].name);
strcat(line[RIGHTSIDE][whichline], " (");
stcl_d(numberstring, jarl[whichjarl].strength);
strcat(line[RIGHTSIDE][whichline], numberstring);
strcat(line[RIGHTSIDE][whichline], "-");
stcl_d(numberstring, jarl[whichjarl].moves);
strcat(line[RIGHTSIDE][whichline], numberstring);
strcat(line[RIGHTSIDE][whichline], ")");
} else
{ strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_UNKNOWN_JARL, "Unknown jarl"));
strcat(line[RIGHTSIDE][whichline], " (?-?)");
}
whichline++;
} }
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ if (monster[whichmonster].alive && monster[whichmonster].where == whichcounter)
{ strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], monstertypes[monster[whichmonster].species]);
strcat(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], monster[whichmonster].name);
strcat(line[RIGHTSIDE][whichline], " (");
stcl_d(numberstring, monster[whichmonster].strength);
strcat(line[RIGHTSIDE][whichline], numberstring);
strcat(line[RIGHTSIDE][whichline], "-");
stcl_d(numberstring, monster[whichmonster].moves);
strcat(line[RIGHTSIDE][whichline], numberstring);
strcat(line[RIGHTSIDE][whichline], ")");
whichline++;
} }
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if
( treasure[whichtreasure].possessortype == KINGDOM
&& treasure[whichtreasure].where == whichcounter
)
{ strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_THE, "The"));
strcat(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], treasure[whichtreasure].name);
whichline++;
} }
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if
( sord[whichsord].possessortype == KINGDOM
&& sord[whichsord].where == whichcounter
)
{ strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
strcat(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], sord[whichsord].name);
whichline++;
} }
if (whichline == oldwhichline)
{ strcpy(line[RIGHTSIDE][whichline], " ");
strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
whichline++;
}
rightlines = whichline;
} elif (countertype == SORD)
{ strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_SWORD_NAME, "Sword Name"));
strcat(line[LEFTSIDE][0], ":");
pad(line[LEFTSIDE][0]);
strcat(line[LEFTSIDE][0], sord[whichcounter].name);
print_location(sord[whichcounter].where, 1);
leftlines = 2; // counting from 1
rightlines = 0;
}
if (leftlines >= rightlines)
{ lines = leftlines;
} else
{ lines = rightlines;
}
if (rightlines > 0)
{ wide = 1;
} else
{ wide = 0;
}
if (!(InfoWindowPtr = (struct Window *) OpenWindowTags(NULL,
WA_Left, (SCREENXPIXEL / 2) - ((360 + (280 * wide )) / 2),
WA_Top, (SCREENYPIXEL / 2) - ( (30 + ( 10 * lines)) / 2),
WA_Width, 360 + (280 * wide ),
WA_Height, 30 + ( 10 * lines),
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
WA_Title, GetCatalogStr(li.li_Catalog, MSG_INFORMATION, "Information"),
WA_Gadgets, NULL,
WA_CustomScreen, ScreenPtr,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_NoCareRefresh, TRUE,
WA_Activate, TRUE,
TAG_DONE))
)
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open information window!\0", 24);
cleanexit(EXIT_FAILURE);
}
/* if (countertype == HERO)
{ SetAPen(InfoWindowPtr->RPort, herocolour[whichcounter]);
} elif (countertype == JARL && jarl[counter].hero != -1)
{ SetAPen(InfoWindowPtr->RPort, herocolour[jarl[whichcounter].hero]);
} elif (countertype == KINGDOM && world[counter].hero != -1)
{ SetAPen(InfoWindowPtr->RPort, herocolour[world[whichcounter].hero]);
} if we had a free pen, we could do this... else
{ */ SetAPen(InfoWindowPtr->RPort, LIGHTGREY);
/* } */
RectFill(InfoWindowPtr->RPort, 8, 13, 360 + (280 * wide) - 10, 30 + (10 * lines) - 6);
SetAPen(InfoWindowPtr->RPort, BLACK);
SetDrMd(InfoWindowPtr->RPort, JAM1);
for (whichline = 0; whichline < leftlines; whichline++)
{ Move(InfoWindowPtr->RPort, 16, 26 + (whichline * 10));
Text(InfoWindowPtr->RPort, line[LEFTSIDE][whichline], strlen(line[LEFTSIDE][whichline]));
}
if (wide)
{ for (whichline = 0; whichline < rightlines; whichline++)
{ Move(InfoWindowPtr->RPort, 320 + 16, 26 + (whichline * 10));
Text(InfoWindowPtr->RPort, line[RIGHTSIDE][whichline], strlen(line[RIGHTSIDE][whichline]));
} }
if (counterrow)
{ if (countertype == HERO)
{ hero_info(whichcounter);
} else
{ assert(countertype == JARL);
jarl_info(whichcounter);
} }
while(!done)
{ Wait(1L << InfoWindowPtr->UserPort->mp_SigBit);
while (MsgPtr = (struct IntuiMessage *) GetMsg(InfoWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
ReplyMsg((struct Message *) MsgPtr);
switch(class)
{
case IDCMP_CLOSEWINDOW:
done = TRUE;
break;
case IDCMP_RAWKEY:
if (!(qual & IEQUALIFIER_REPEAT) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
{ done = TRUE;
}
break;
default:
break;
} } }
if (counterrow)
{ uninfo();
}
CloseWindow(InfoWindowPtr);
InfoWindowPtr = NULL;
clearkybd();
}
MODULE void getdefender(SLONG attackhero, SLONG here)
{ FLAG done = FALSE;
SLONG counter, countertype, defendtype, defender, whichattack,
whichjarl;
do
{ saywho(HERO, attackhero, TRUE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SELECT_DEFENDER, "select defender"));
strcat(saystring, "?");
say(LOWER);
counter = getevent(COUNTER, &countertype);
if (counter == -2 || counter == -3)
{ // user wants to quit (back to `select attacker')
if (hero[attackhero].attacking)
{ deselect_hero(attackhero, TRUE);
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].attacking)
{ deselect_jarl(whichjarl, TRUE);
} }
return;
} elif (countertype == HERO) // if an enemy hero
{ if (counter != attackhero && hero[counter].where == here)
{ defendtype = HERO;
defender = counter;
done = TRUE;
} }
elif (countertype == JARL) // if an enemy jarl
{ if (jarl[counter].hero != attackhero && jarl[counter].where == here)
{ defendtype = JARL;
defender = counter;
done = TRUE;
} }
elif (countertype == MONSTER) // if a monster
{ if (monster[counter].where == here)
{ defendtype = MONSTER;
defender = counter;
done = TRUE;
} }
elif (countertype == KINGDOM)
{ if
( world[counter].hero != attackhero
&& counter <= 35
&& counter == here
)
{ defendtype = KINGDOM;
defender = counter;
done = TRUE;
} }
if (done)
{ if (hero[attackhero].attacking)
{ // check if the hero has already fought this
for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
{ if
( hero[attackhero].attacktype[whichattack] == countertype
&& hero[attackhero].attacked[whichattack] == counter
)
{ done = FALSE;
saywho(HERO, attackhero, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_H_A_F_T_T_T, "has already fought that this turn"));
strcat(saystring, ".");
say(LOWER);
anykey();
break; // for speed
} } }
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
{ if
( jarl[whichjarl].attacktype[whichattack] == countertype
&& jarl[whichjarl].attacked[whichattack] == counter
)
{ done = FALSE;
saywho(JARL, whichjarl, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_H_A_F_T_T_T, "has already fought that this turn"));
strcat(saystring, ".");
say(LOWER);
anykey();
break; // for speed
} } } } }
else
{ ; // DisplayBeep(ScreenPtr);
} }
while (!done);
// ok, going ahead with the battle
if (countertype == JARL && jarl[counter].face == FACEDOWN)
{ revealjarl(counter, TRUE);
}
if (hero[attackhero].attacking)
{ for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
{ if (hero[attackhero].attacktype[whichattack] == -1)
{ hero[attackhero].attacktype[whichattack] = countertype;
hero[attackhero].attacked[whichattack] = counter;
break;
} } }
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
{ if (jarl[whichjarl].attacktype[whichattack] == -1)
{ jarl[whichjarl].attacktype[whichattack] = countertype;
jarl[whichjarl].attacked[whichattack] = counter;
break;
} } } }
dobattle(countertype, counter, attackhero);
}
MODULE FLAG needsord(SLONG countertype, SLONG counter)
{ SLONG whichsord;
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if
( sord[whichsord].possessortype == countertype
&& sord[whichsord].possessor == counter
)
{ return(FALSE);
} }
return(TRUE);
}
MODULE void brosung(SLONG countertype, SLONG whichcounter)
{ SLONG result, whichconnection, whichmonster, whichtreasure, where;
for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
{ if (countertype == HERO)
{ where = world[hero[whichcounter].where].connection[whichconnection];
} else
{ assert(countertype == JARL);
where = world[jarl[whichcounter].where].connection[whichconnection];
}
if (where == -1)
{ break;
}
for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
{ if
( monster[whichmonster].alive
&& monster[whichmonster].species == DRAGON
&& monster[whichmonster].where == where
)
{ // there is a dragon here
for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
{ if
( treasure[whichtreasure].possessortype == MONSTER
&& treasure[whichtreasure].possessor == whichmonster
)
{ /* We know it is human control because we
don't call this function for Amiga heroes/jarls */
saywho(countertype, whichcounter, TRUE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_EXCHANGE_THE, "exchange the"));
strcat(saystring, " ");
strcat(saystring, treasure[BROSUNGNECKLACE].name);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_WITH, "with"));
strcat(saystring, " ");
strcat(saystring, monstertypes[DRAGON]);
strcat(saystring, " ");
strcat(saystring, monster[whichmonster].name);
strcat(saystring, " (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
strcat(saystring, "/");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
strcat(saystring, ")?");
say(LOWER);
do
{ result = getevent(KEYBOARD, NULL);
} while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
if (result == onekey[ONEKEY_YES])
{ // give the dragon's treasure to the hero/jarl
treasure[whichtreasure].possessortype = countertype;
treasure[whichtreasure].possessor = whichcounter;
saywho(countertype, whichcounter, TRUE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_THE, "takes the"));
strcat(saystring, " ");
strcat(saystring, treasure[whichtreasure].name);
strcat(saystring, ".");
say(LOWER);
// give the hero/jarl's treasure to the dragon
treasure[BROSUNGNECKLACE].possessortype = MONSTER;
treasure[BROSUNGNECKLACE].possessor = whichmonster;
break;
} } } } } } }
MODULE void flash(SLONG country)
{ SLONG colour;
if (country < 0 || country > 65)
{ return;
}
if (country == 9)
{ colour = 89; // Suder Gotland
} elif (country == 10)
{ colour = 90; // Juteland
} elif (country == 11)
{ colour = 91; // Scandia
} else
{ colour = country + 8;
}
SetRGB4(&ScreenPtr->ViewPort, colour, 15, 15, 15); // white flash
Delay(2); // hold the flash
if (country >= 36)
{ SetRGB4(&ScreenPtr->ViewPort, colour, 0, 0, 9); // dark blue
} elif (world[country].hero != -1)
{ SetRGB4
( &ScreenPtr->ViewPort,
colour,
herocolour[world[country].hero].red,
herocolour[world[country].hero].green,
herocolour[world[country].hero].blue
);
} elif (world[country].is)
{ SetRGB4(&ScreenPtr->ViewPort, colour, 12, 12, 12); // light grey ice
} else
{ SetRGB4
( &ScreenPtr->ViewPort,
colour,
taxcolours[world[country].tax].red,
taxcolours[world[country].tax].green,
taxcolours[world[country].tax].blue
);
} }
MODULE FLAG assess(SLONG countertype, SLONG counter)
{ return(FALSE);
}
MODULE void promote(SLONG whichhero, SLONG whichjarl)
{ remove_jarl(whichjarl, TRUE);
jarl[whichjarl].alive = FALSE;
hero[whichhero].alive = TRUE;
hero[whichhero].promoted = whichjarl;
hero[whichhero].name = jarl[whichjarl].name;
hero[whichhero].moves = jarl[whichjarl].moves;
hero[whichhero].strength = jarl[whichjarl].strength;
hero[whichhero].where = jarl[whichjarl].where;
hero[whichhero].homewhere = jarl[whichjarl].homewhere;
hero[whichhero].god =
hero[whichhero].rune = -1;
hero[whichhero].maidens =
hero[whichhero].glory = 0;
hero[whichhero].hagall = jarl[whichjarl].hagall;
hero[whichhero].loseturn = jarl[whichjarl].loseturn;
hero[whichhero].wealth = jarl[whichjarl].wealth;
hero[whichhero].wounded = FALSE;
deselect_hero(whichhero, TRUE);
move_hero(whichhero, TRUE);
}
MODULE void withdraw(SLONG whichhero)
{ SLONG whichcountry, whichjarl;
hero[whichhero].verydead = TRUE;
// all the jarls of the dead hero are freed
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
{ jarl[whichjarl].hero = -1;
} }
// all the kingdoms of the dead hero declare independence
for (whichcountry = 0; whichcountry <= 35; whichcountry++)
{ if (world[whichcountry].hero == whichhero)
{ world[whichcountry].hero = -1;
} }
darken();
}
MODULE FLAG asksord(SLONG countertype, SLONG counter, SLONG whichsord)
{ SLONG result, whichcountry;
if (countertype == JARL)
{ whichcountry = jarl[counter].where;
} else
{ whichcountry = hero[counter].where;
}
saywho(countertype, counter, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
strcat(saystring, " ");
strcat(saystring, world[whichcountry].name);
strcat(saystring, ", ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKE_SWORD, "take sword"));
strcat(saystring, " ");
strcat(saystring, sord[whichsord].name);
strcat(saystring, " (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
strcat(saystring, "/");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
strcat(saystring, ")?");
say(LOWER);
do
{ result = getevent(KEYBOARD, NULL);
} while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
if (result == onekey[ONEKEY_YES])
{ remove_sord(whichsord, TRUE);
sord[whichsord].possessortype = countertype;
sord[whichsord].possessor = counter;
sord[whichsord].where = -1;
return(TRUE);
}
// assert(result == onekey[ONEKEY_NO]);
return(FALSE);
}
MODULE void asktreasure(SLONG countertype, SLONG counter, SLONG whichtreasure)
{ SLONG result, whichcountry;
if (countertype == JARL)
{ whichcountry = jarl[counter].where;
} else
{ whichcountry = hero[counter].where;
}
saywho(countertype, counter, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
strcat(saystring, " ");
strcat(saystring, world[whichcountry].name);
strcat(saystring, ", ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKE_THE, "take the"));
strcat(saystring, " ");
strcat(saystring, treasure[whichtreasure].name);
strcat(saystring, " (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
strcat(saystring, "/");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
strcat(saystring, ")?");
say(LOWER);
do
{ result = getevent(KEYBOARD, NULL);
} while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
if (result == onekey[ONEKEY_YES])
{ remove_treasure(whichtreasure, TRUE);
treasure[whichtreasure].possessortype = countertype;
treasure[whichtreasure].possessor = counter;
treasure[whichtreasure].where = -1;
} }
MODULE void pad(STRPTR thestring)
{ SLONG i, length;
length = strlen(thestring);
if (length < 21)
{ for (i = length; i <= 21; i++)
{ strcat(thestring, " ");
} } }
MODULE void print_location(SLONG whichcountry, SLONG index)
{ strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_LOCATION, "Location"));
strcat(line[LEFTSIDE][index], ":");
pad(line[LEFTSIDE][index]);
strcat(line[LEFTSIDE][index], world[whichcountry].name);
strcat(line[LEFTSIDE][index], " (");
stcl_d(numberstring, world[whichcountry].tax);
strcat(line[LEFTSIDE][index], numberstring);
strcat(line[LEFTSIDE][index], ")");
}
MODULE void print_sea(SLONG sea_value, SLONG index)
{ strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_MOVE_BY_SEA, "Move by sea"));
strcat(line[LEFTSIDE][index], "?");
pad(line[LEFTSIDE][index]);
if (sea_value == NORMAL)
{ strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
} elif (sea_value == BAD)
{ strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
} else
{ // assert(sea_value == GOOD);
strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_SPECIAL, "Special"));
} }
MODULE void print_hagall(SLONG hagall_value, SLONG index)
{ strcpy(line[LEFTSIDE][index], "Hagall (");
strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_SLOWED, "slowed"));
strcat(line[LEFTSIDE][index], ")?");
pad(line[LEFTSIDE][index]);
if (hagall_value)
{ strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
} else
{ strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
} }
MODULE void print_paralyzed(SLONG loseturn_value, SLONG index)
{ strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_PARALYZED, "Paralyzed"));
strcat(line[LEFTSIDE][index], "?");
pad(line[LEFTSIDE][index]);
if (loseturn_value)
{ strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
} else
{ strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
} }
MODULE void print_routed(SLONG routed_value, SLONG index)
{ strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_ROUTED, "Routed"));
strcat(line[LEFTSIDE][index], "?");
pad(line[LEFTSIDE][index]);
if (routed_value)
{ strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
} else
{ strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
} }
MODULE void amiga_attack(SLONG attackhero, SLONG defendtype, SLONG defender)
{ SLONG whichattack, whichjarl;
// ok, going ahead with the battle
if (defendtype == JARL && jarl[defender].face == FACEDOWN)
{ revealjarl(defender, TRUE);
}
if (hero[attackhero].attacking)
{ for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
{ if (hero[attackhero].attacktype[whichattack] == -1)
{ hero[attackhero].attacktype[whichattack] = defendtype;
hero[attackhero].attacked[whichattack] = defender;
break;
} } }
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
{ if (jarl[whichjarl].attacktype[whichattack] == -1)
{ jarl[whichjarl].attacktype[whichattack] = defendtype;
jarl[whichjarl].attacked[whichattack] = defender;
break;
} } } }
saywho(HERO, attackhero, FALSE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKS, "attacks"));
if (defendtype == HERO || defendtype == JARL)
{ saywho(defendtype, defender, FALSE, TRUE);
} elif (defendtype == MONSTER)
{ strcat(saystring, " ");
strcat(saystring, monstertypes[monster[defender].species]);
strcat(saystring, " ");
strcat(saystring, monster[defender].name);
} else
{ // assert(defendtype == KINGDOM);
strcat(saystring, " ");
if (world[defender].hero != -1)
{ strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
strcat(saystring, " ");
strcat(saystring, hero[world[defender].hero].name);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S, "'s"));
strcat(saystring, " ");
}
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_KINGDOM, "kingdom"));
strcat(saystring, " ");
strcat(saystring, world[defender].name);
strcat(saystring, " (");
stcl_d(numberstring, world[defender].tax);
strcat(saystring, numberstring);
strcat(saystring, ")");
}
strcat(saystring, ".");
say(LOWER);
anykey();
dobattle(defendtype, defender, attackhero);
}
MODULE FLAG ask_faxi(SLONG countertype, SLONG whichcounter)
{ SLONG result;
saywho(countertype, whichcounter, TRUE, FALSE);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RIDE_THE, "ride the"));
strcat(saystring, " ");
strcat(saystring, treasure[FREYFAXI].name);
strcat(saystring, " (");
stcl_d(numberstring, faxirides);
strcat(saystring, numberstring);
strcat(saystring, " ");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RIDES2, "rides"));
strcat(saystring, ") (");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
strcat(saystring, "/");
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
strcat(saystring, ")?");
say(LOWER);
do
{ result = getevent(KEYBOARD, NULL);
} while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
if (result == onekey[ONEKEY_YES])
{ faxirides--;
faxi_disappear();
return(TRUE);
}
return(FALSE);
}
MODULE void saywho(SLONG countertype, SLONG counter, FLAG comma, FLAG lowercase)
{ if (!lowercase)
{ saystring[0] = 0;
} else
{ strcat(saystring, " ");
}
if (countertype == HERO)
{ if (!lowercase)
{ strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
} else
{ strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
}
strcat(saystring, " ");
strcat(saystring, hero[counter].name);
} else
{ // assert(countertype == JARL);
if (jarl[counter].hero != -1)
{ if (!lowercase)
{ strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
} else
{ strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
}
strcat(saystring, " ");
strcat(saystring, hero[jarl[counter].hero].name);
strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_JARL, "'s jarl"));
} else
{ if (!lowercase)
{ strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_JARL, "Jarl"));
} else
{ strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_JARL2, "jarl"));
} }
strcat(saystring, " ");
strcat(saystring, jarl[counter].name);
}
if (!lowercase)
{ if (comma)
{ strcat(saystring, ",");
}
strcat(saystring, " ");
} }
MODULE FLAG attackersleft(void)
{ SLONG whichhero, whichjarl;
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ if (hero[whichhero].attacking)
{ return(TRUE);
} }
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].attacking)
{ return(TRUE);
} }
return(FALSE);
}
MODULE void summarywindow(void)
{ SLONG i,
jarls,
kingdoms,
length,
treasures,
wealth,
whichcountry,
whichjarl,
whichhero,
whichtreasure,
whichsord;
FLAG done = FALSE,
ok;
ULONG class;
UWORD code, qual;
struct IntuiMessage* MsgPtr;
strcpy(line[0][0], GetCatalogStr(li.li_Catalog, MSG_SUMMARYLINE, "Hero Name C-M J K S T C S R Glry Luck $$$$"));
/* Hero Name C-M J K S T C S R Glry Luck $$$$
o o a i w r o t u
m v r n o e n a n
b e l g r a t t e
a m s d d s r u s
t e o u o s
n m r l
t s e
s
Heldenname K-B J K S S K S @ Ruhm Glck $$$$
a e a ö c c o t @
m w r n h h n a @
p e l i w ä t t @
f g s g e t r u @
u r r z o s @
n e t e l
g i l
s c e
h
e */
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ strcpy(line[0][whichhero + 1], hero[whichhero].name);
length = strlen(hero[whichhero].name);
for (i = length; i < 11; i++)
{ strcat(line[0][whichhero + 1], " ");
}
stcl_d(numberstring, hero[whichhero].strength);
strcat(line[0][whichhero + 1], numberstring);
strcat(line[0][whichhero + 1], "-");
stcl_d(numberstring, hero[whichhero].moves);
strcat(line[0][whichhero + 1], numberstring);
strcat(line[0][whichhero + 1], " ");
jarls = 0;
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
{ jarls++;
} }
stcl_d(numberstring, jarls);
strcat(line[0][whichhero + 1], numberstring);
strcat(line[0][whichhero + 1], " ");
kingdoms = 0;
for (whichcountry = 0; whichcountry <= 35; whichcountry++)
{ if (world[whichcountry].hero == whichhero)
{ kingdoms++;
} }
stcl_d(numberstring, kingdoms);
strcat(line[0][whichhero + 1], numberstring);
strcat(line[0][whichhero + 1], " ");
ok = FALSE;
for (whichsord = 0; whichsord <= SORDS; whichsord++)
{ if
( sord[whichsord].possessortype == HERO
&& sord[whichsord].possessor == whichhero
)
{ numberstring[0] = sord[whichsord].name[0];
numberstring[1] = 0;
strcat(line[0][whichhero + 1], numberstring);
ok = TRUE;
break;
} }
if (!ok)
{ strcat(line[0][whichhero + 1], "-");
}
strcat(line[0][whichhero + 1], " ");
treasures = 0;
for (whichtreasure = 0; whichtreasure <= SORDS; whichtreasure++)
{ if
( ( treasure[whichtreasure].possessortype == HERO
&& treasure[whichtreasure].possessor == whichhero
)
|| ( treasure[whichtreasure].possessortype == JARL
&& jarl[treasure[whichtreasure].possessor].hero == whichhero
) )
{ treasures++;
} }
stcl_d(numberstring, treasures);
strcat(line[0][whichhero + 1], numberstring);
strcat(line[0][whichhero + 1], " ");
if (hero[whichhero].control == HUMAN)
{ strcat(line[0][whichhero + 1], GetCatalogStr(li.li_Catalog, MSG_CHAR_HUMAN, "H"));
} elif (hero[whichhero].control == AMIGA)
{ strcat(line[0][whichhero + 1], "A");
} else
{ // assert(hero[whichhero].control == NONE);
strcat(line[0][whichhero + 1], "-");
}
strcat(line[0][whichhero + 1], " ");
if (!hero[whichhero].alive)
{ strcat(line[0][whichhero + 1], GetCatalogStr(li.li_Catalog, MSG_CHAR_DEAD, "D"));
} elif (hero[whichhero].wounded)
{ strcat(line[0][whichhero + 1], GetCatalogStr(li.li_Catalog, MSG_CHAR_WOUNDED, "W"));
} else
{ strcat(line[0][whichhero + 1], GetCatalogStr(li.li_Catalog, MSG_CHAR_GOOD, "G"));
}
strcat(line[0][whichhero + 1], " ");
if (hero[whichhero].rune == -1)
{ strcat(line[0][whichhero + 1], "-");
} else
{ numberstring[0] = runename[hero[whichhero].rune][0];
numberstring[1] = 0;
strcat(line[0][whichhero + 1], numberstring);
}
stcl_d(numberstring, hero[whichhero].glory);
length = strlen(numberstring);
for (i = length; i < 5; i++)
{ strcat(line[0][whichhero + 1], " ");
}
strcat(line[0][whichhero + 1], numberstring);
stcl_d(numberstring, hero[whichhero].luck);
length = strlen(numberstring);
for (i = length; i < 5; i++)
{ strcat(line[0][whichhero + 1], " ");
}
strcat(line[0][whichhero + 1], numberstring);
wealth = hero[whichhero].wealth;
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
{ wealth += jarl[whichjarl].wealth;
} }
stcl_d(numberstring, wealth);
length = strlen(numberstring);
for (i = length; i < 5; i++)
{ strcat(line[0][whichhero + 1], " ");
}
strcat(line[0][whichhero + 1], numberstring);
}
if (!(InfoWindowPtr = (struct Window *) OpenWindowTags(NULL,
WA_Left, (SCREENXPIXEL / 2) - (378 / 2),
WA_Top, (SCREENYPIXEL / 2) - (102 / 2),
WA_Width, 378,
WA_Height, 102,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
WA_Title, GetCatalogStr(li.li_Catalog, MSG_GAME_SUMMARY, "Game Summary"),
WA_Gadgets, NULL,
WA_CustomScreen, ScreenPtr,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_NoCareRefresh, TRUE,
WA_Activate, TRUE,
TAG_DONE))
)
{ DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open summary window!\0", 24);
cleanexit(EXIT_FAILURE);
}
RectFill(InfoWindowPtr->RPort, 8, 13, 378 - 10, 102 - 6);
SetAPen(InfoWindowPtr->RPort, BLACK);
SetDrMd(InfoWindowPtr->RPort, JAM1);
Move(InfoWindowPtr->RPort, 16, 26);
Text(InfoWindowPtr->RPort, line[0][0], strlen(line[0][0]));
for (whichhero = 0; whichhero <= HEROES; whichhero++)
{ Move(InfoWindowPtr->RPort, 16, 38 + (whichhero * 10));
Text(InfoWindowPtr->RPort, line[0][whichhero + 1], strlen(line[0][whichhero + 1]));
}
Move(InfoWindowPtr->RPort, 16, 29);
Draw(InfoWindowPtr->RPort, 368 - 10, 29);
while(!done)
{ Wait(1L << InfoWindowPtr->UserPort->mp_SigBit);
while (MsgPtr = (struct IntuiMessage *) GetMsg(InfoWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
ReplyMsg((struct Message *) MsgPtr);
switch(class)
{
case IDCMP_CLOSEWINDOW:
done = TRUE;
break;
case IDCMP_RAWKEY:
if (!(qual & IEQUALIFIER_REPEAT) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
{ done = TRUE;
}
break;
default:
break;
} } }
CloseWindow(InfoWindowPtr);
InfoWindowPtr = NULL;
clearkybd();
}
MODULE SLONG getattackers(SLONG whichhero, SLONG whichcountry)
{ SLONG whichjarl,
totalstrength = 0;
FLAG ok = FALSE;
if (hero[whichhero].alive && !hero[whichhero].routed && hero[whichhero].where == whichcountry)
{ hero[whichhero].attacking = TRUE;
select_hero(whichhero, FALSE);
ok = TRUE;
totalstrength += hero[whichhero].strength;
}
for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
{ if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero && !jarl[whichjarl].routed && jarl[whichjarl].where == whichcountry)
{ jarl[whichjarl].attacking = TRUE;
select_jarl(whichjarl, FALSE);
ok = TRUE;
totalstrength += jarl[whichjarl].strength;
} }
if (ok)
{ refreshcounters();
}
return(totalstrength);
}